Matt Murphy Matt Murphy - 2 months ago 5
Node.js Question

JavaScript arrays: string indexed items

I've had a bit of a wakeup to the nature of JavaScript array indexes recently. Pursuing it, I found the following (I'm working with Node.js in interpretive mode here):

var x=[];
console.log(x); // Yields [ a: 'a' ]
console.log(x.length); // yields 0 not 1
console.log(x); // Yields [ , 1, a: 'a' ]
console.log(x.length); // Yields 2 not 3 (one for empty 0 space, one for the occupied 1 space)

a: 'a'
really what it looks like - an object property embedded in an array - and, thus, isn't counted in the array property


In JavaScript, arrays are just objects with some special properties, such as an automatic length property, and some methods attached (such as sort, pop, join, etc.). Indeed, a will not be counted in your array, since the length property of an array only stores the amount of elements with a property name that can be represented with a 32-bit positive integer.

And since arrays always automatically define every numbered element up to the highest element with a positive 32-bit int property name, this effectively means the length property stores 1 higher than the element with the highest 32-bit integer as a property name. Thanks @Felix Kling for correcting me about this in the comments.

Adding properties such as a is not forbidden at all, but you should watch out with them, since it might be confusing when reading your code.

There's also a difference in walking through the elements in the array:

To walk through all the numbered elements:

for (var i=0; i<myArray.length; i++) {
    //do something

To walk through every property that's not built-in:

for (var i in myArray) {
    //do something

Note that this loop will also include anything that's included from Array.prototype that's not a built-in method. So, if you were to add Array.prototype.sum = function() {/*...*/};, it will also be looped through.

To find out if the object you're using is indeed an array, and not just an object, you could perform the following test:

if ( === '[object Array]') {
    //myObject is an array
} else if (typeof myObject === 'object') {
    //myObject is some other kind of object

See @artem's comment: myObject instanceof Array might not always work correctly.