3

I'm working through a tutorial on JavaScript's call and apply methods, and am confused by the behavior of an 'array-like object' used in the example:

var arrayLikeObj = {
    0: 'Marty',
    1: 78,
    2: 42,
    3: ['Tim', 'Eric', 'Phil'],
    length: 4
};

My understanding is that the length property here is wholly unrelated to the Array.prototype.length method, and was hard-coded in order to give the object it's necessary array-like properties.

However, when I pop the array-like object as such:

console.log(Array.prototype.pop.call(arrayLikeObj));

...it's length property has decreased!

console.log(arrayLikeObj) // Object {0: "Marty", 1: 78, 2: 42, length: 3} 

How is this possible!?

Does Array.prototype.length somehow overwrite the existing length property in the object, turning it into a length method?

To further my confusion, when I declare an object without the hard-coded length property and call the same pop method:

var arrayLikeObj = {
        0: 'Marty',
        1: 78,
        2: 42,
        3: ['Tim', 'Eric', 'Phil']
    };

console.log(Array.prototype.pop.call(arrayLikeObj));
console.log(arrayLikeObj);

The returned object has been assigned a length of 0:

{0: "Marty", 1: 78, 2: 42, 3: Array[3], length: 0}

I am very interested in understanding what is happening here.

Sumner Evans
  • 8,951
  • 5
  • 30
  • 47
i_made_that
  • 941
  • 1
  • 8
  • 19
  • Because that's what that methods does. It is described to modify a `.length` property on the `this` object it was given. [ECMAScript 5 - 15.4.4.6 Array.prototype.pop](http://es5.github.io/#x15.4.4.6) If there's no `.length`, it gets a default `0` value. *"If len is zero, a. Call the [[Put]] internal method of O with arguments "length", 0, and true; b. return undefined"* – cookie monster Apr 05 '14 at 01:44
  • Note that most, if not all, of the `Array.prototype` methods have a version of the following: *"The `pop` 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."* – cookie monster Apr 05 '14 at 01:51
  • Related: [How does Array.prototype.slice.call() work](http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work) – cookie monster Apr 05 '14 at 01:53

1 Answers1

3

Array.prototype.pop creates a length property for the object.

http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.6

It happens in steps 4.a and 5.d. In the second case you posted, note that the [[Get]] internal method returns undefined (since there is no length property), and ToUint32(undefined) first converts undefined to NaN and then converts NaN to 0.

guest
  • 6,450
  • 30
  • 44