3

JavaScript seems to calculate the array length property by the number of the last index in the array rather than counting the number of items in the array. Example:

var testArray = ['a', 'b', 'c'];
console.log(testArray.length); //3
testArray[8] = 'i';
console.log(testArray.length); //9

Normally I would use push() and wouldn't add a value to an array using bracket notation, but this was a bit of a surprise. Is there any reason for this implementation of assigning a value to Array.length? The only thing I can seem to come up with is that it just uses the last index as a performance optimization to avoid counting the array items.

1
  • The simplest reason is: because that's what the specification says to do.
    – TehShrike
    Apr 8, 2013 at 2:31

2 Answers 2

8

The length of an array is the number of elements it contains whereby it does not matter if those elements are valid objects or values or just "undefined". If you add an element at position 8 you automatically generate 5 additional elements between your first three elements and the new one as you can see if you run

for(var i = 0; i < testArray.length; i++){console.log(testArray[i]);}

(Those may or may not take real space in memory, depending on the actual implementation)

Being "equaly spaced" is somewhat the definition of an array (compared to other container types like lists or dictionaries).

3
  • 2
    No elements are generated in the array, it has items at indices 0, 1, 2 and 8. Use console.dir on the array to get better overlook.
    – Esailija
    Apr 7, 2013 at 12:18
  • Interesting, I didn't catch that. I inspected it in the console, but didn't loop over the array. Apr 7, 2013 at 12:19
  • @Esailija If you do console.dir(testArray.slice(0,-1)) displays ['a', 'b', 'c'], but testArray.slice(0,-1).length return 8. They're there. Apr 7, 2013 at 20:27
2

I rather think it is the other way around: last index is based on the length. I think JS may just be setting the length for you behind the scenes when you assign a value to an (as yet) non-existing index. Which means that you could read your:

testArray[8] = 'h';

as

SetLength(testArray, 9); // or something similar (I'm not too familiar with JS)
testArray[8] = 'h';

There are a few language out there that allow for arrays with other starting indices, but most arrays that allow for dynamic allocation/sizing will have zero-based indices. And that means that there is always a fixed relation between the length of the array and the last index number:

Last index number = Length - 1

Update

JS doesn't do a last index + 1 to get the count. When you do testArray[8] = 'h'; JS doesn't just set the length to 8 + 1. It first checks how many elements are already in the array. When the array does not yet have enough elements to store something at index 8, it will resize. It resizes the array to just large enough to hold something at index 8, which, because arrays are zero-based, means resizing to 8 + 1.

Length <> number of stored elements

That doesn't mean the array then holds 9 elements. It just means that the array has enough room to do so. If you create an array by just testArray[8] = 'h';, you are essentially telling JS to allocate enough room for 9 elements and store 'h' at the element with index 8.

3
  • 1
    Right, I get that it's doing lastIndex + 1 to set the length, but my question is why it would do that rather than getting the true count by counting the number of items. Apr 7, 2013 at 12:15
  • @VirtuosiMedia: How do you know it doesn't? But why should it? Arrays, I think per definition, can't have "holes" in them. Apr 7, 2013 at 12:17
  • And by the way it doesn't do Last Index + 1, because there may not be an element at 8 yet. The array may still be of length = 3 when you do the testArray[8] assignment. @Thorsten explains it better. Apr 7, 2013 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.