Array.length gives the wrong length

If I have an array having an object as values ​​at indices such as:

var a = []; a[21] = {}; a[90] = {}; a[13] = {}; alert(a.length); // outputs 91 

I found a workaround to get the actual length:

 function getLength(arr) { return Object.keys(arr).length; } var a = []; a[21] = {}; a[90] = {}; a[13] = {}; alert(getLength(a)); 

But why does JS give the wrong length when objects are stored at random indexes? It simply adds 1 to the largest index found in the array. As in the example above, 90 was the largest index. He just adds 1 and gives the result 91. Demo

+8
javascript arrays
source share
4 answers

This is because length gives you the next index available in the array.

Docs

arrayLength

If the only argument passed to the Array constructor is an integer from 0 to 2 ^ 32-1 (inclusive), this returns a new JavaScript array with the length set for that number.

ECMA Specifications

Since you did not insert any element into keys other than 21, 90, 13, all other indexes contain undefined . Demo

To get the actual number of elements in an array:

 var a = []; a[21] = {}; a[90] = {}; a[13] = {}; var len = 0; for (var i = 0; i < a.length; i++) { if (a[i] !== undefined) { len++; } } document.write(len); 

Shorter version

 var a = []; a[21] = {}; a[90] = {}; a[13] = {}; for (var i = 0, len = 0; i < a.length; i++, a[i] !== undefined && len++); document.write(len); 

Demo

EDIT

If the array contains a large number of elements, a loop to get its length is not the best choice.

As you already mentioned in the question, Object.keys(arr).length is the best solution in this case, given that you do not have any properties added to this array. Otherwise, length will not be what you expect. (Thanks @RobG)

+8
source share

Because this is the behavior of Array.length, as described in the ECMAScript specification .

The length property of this Array is a data property whose value is always numerically greater than the name of each property to delete, whose name is the index of the array.

So Array.length is always the last index of an element + 1.

+3
source share

An array in JavaScript is a simple zero-level structure. array.length returns n + 1 , where n is the maximum index in the array.

Here's how it works: when you assign the 90th element and the length of this array is less than 90, it expands the array to 90 and sets the value of the 90th element. All missing values ​​are interpreted as null .

If you try the following code:

 var a = []; a[21] = {}; a[90] = {}; a[13] = {}; console.log(JSON.stringify(a)); 

You will get the following JSON:

[NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, {}, NULL, NULL, NULL, NULL, NULL, NULL, NULL, {}, NULL, NULL , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, {}]

In addition, array.length not a read-only value.
If you set the length value to less than the current one, the size of the array will be resized:

  var arr = [1,2,3,4,5]; arr.length = 3; console.log(JSON.stringify(arr)); // [1,2,3] 

If you set the length value to more than the current one, then the array will also be expanded:

  var arr = [1,2,3]; arr.length = 5; console.log(JSON.stringify(arr)); // [1,2,3,null,null] 

If you need to assign such values, you can use JS objects.
You can use them as an associative array and assign any key-value pairs.

 var a = {}; a[21] = 'a'; a[90] = 'b'; a[13] = 'c'; a['stringkey'] = 'd'; a.stringparam = 'e'; // btw, a['stringkey'] and a.stringkey is the same console.log(JSON.stringify(a)); // returns {"13":"c","21":"a","90":"b","stringkey":"d","stringparam":"e"} console.log(Object.keys(a).length); // returns 5 
+3
source share

This is because you have [90] as the largest index, so the index starts from 0 to 90, becomes 91 in length.

And where you did not pass values ​​like [80] etc. javascript will save them as a hole, for example, [1, , 3, , ,90] ,, 3,,, [1, , 3, , ,90] , where commas are used, indicates a hole in the array.

If you try to access these values, you will get undefined .

0
source share

All Articles