Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the length of the array change when I add a new property?

var arr = ["Hello", "There", 123, 456, {
    show: function (value) {
        alert(value);
    }
}];
arr[4].show(arr[0]);
arr["Hello"] = {
    damn: function () {
        alert("What's happening yo !");
    }
}
arr.Hello.damn();
alert("Arr length is: " + arr.length);
like image 202
Storm Avatar asked Apr 29 '15 04:04

Storm


Video Answer


2 Answers

Quoting ECMA Script 5 Specification of Array Objects,

A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232−1.

Since Hello is not valid, according to the above definition, it is not considered as an array index but just as an ordinary property.

Quoting MDN's Relationship between length and numerical properties section,

When setting a property on a JavaScript array when the property is a valid array index and that index is outside the current bounds of the array, the engine will update the array's length property accordingly

So, only if the property is a valid array index, the length property will be adjusted.

In your case, you have just created a new property Hello on the array object.


Note: Only the numerical properties will be used in all of the Array's prototype functions, like forEach, map, etc.

For example, the array shown in question, when used with forEach,

arr.forEach(function(currentItem, index) {
    console.log(currentItem, index);
})

would print

Hello 0
There 1
123 2
456 3
{ show: [Function] } 4

even though the list of keys shows Hello.

console.log(Object.keys(arr));
// [ '0', '1', '2', '3', '4', 'Hello' ]

It is because, Array is derived from Object,

console.log(arr instanceof Object);
// true

and Hello is a valid key of the array object, but just not a valid array index. So, when you treat the array as an Object, Hello will be included in the keys, but the array specific functions will include only the numerical properties.

like image 168
thefourtheye Avatar answered Nov 15 '22 10:11

thefourtheye


This happens because length is only updated when a new numeric property is added to the array as required by the specification:

The length property of this Array object is a data property whose value is always numerically greater than the name of every deletable property whose name is an array index.

And an array index is specified to be:

A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232−1.

However, arrays are also objects - so you can add non-array-index properties to an array, just like you can add properties to any other JavaScript object (which is why your example doesn't throw either).

like image 27
Sean Vieira Avatar answered Nov 15 '22 08:11

Sean Vieira