4

We have an object and then call .push and print the object and its length:

var obj = {
    '2': 3,
    '3': 4,
    'length': 2,
    'splice': Array.prototype.splice,
    'push': Array.prototype.push
};

obj.push(1);
obj.push(2);
console.log(obj);
console.log(obj.length);

This it outputs (in Chrome):

var obj = {
    '2': 1,
    '3': 2,
    'length': 4,
    'splice': Array.prototype.splice,
    'push': Array.prototype.push
};
4

Want to know why do we get this result?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Franki
  • 43
  • 5
  • Why would you want to do this in the first place? You take a method from `Array`, you forcefully inject it in a object, and then you're puzzled because the result of your experiment behaves strangely? Why are you even trying to push things in a object? It's not meant to do this, it's not an array – Jeremy Thille Dec 01 '20 at 14:48
  • 2
    @JeremyThille what you're saying is not true. That object is [an array-like](https://stackoverflow.com/q/29707568). The array methods like `push` are *explicitly* implemented generically so they can be applied to any array-like object. Therefore, this code is not only *correct*, it's correct *by design*. And it operates exactly as it should, there is no mistake or "strangeness" here aside from OP not knowing what to expect. – VLAZ Dec 01 '20 at 14:51

1 Answers1

5

You can think of push like this:

function push(val) {
    this[this.length] = val;
    this.length ++;
}

So, since length is 2, it'll set obj[2] to 1 for the first push and set length to 3. Then, it'll set obj[3] to 2 for the second push and set length to 4, giving you your final result.

Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • Excellent answer! I'd just like to add that [Array.prototype.push is generic by design](https://tc39.es/ecma262/#sec-array.prototype.push): "*Note 2 The **push** function is intentionally generic; it does not require that its **this** value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.*" – VLAZ Dec 01 '20 at 14:56