Nate Rook
Nate Rook

Reputation: 365

How do I find out the number of elements in a Javascript array?

In the ECMAScript specification, array.length is not defined as the number of elements in an array.

http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-array-instances-length

The length property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

That is, a Javascript engine could cause array.length to be positive infinity in all cases, and it would be compliant with the standard.

Taking this into account, how should I count the elements in an array?

Upvotes: 1

Views: 326

Answers (3)

The Witness
The Witness

Reputation: 920

Changing .length property is prevented by Chrome. Run this:

var x = [];
x.length = +Infinity; // Uncaught RangeError: Invalid array length

So, luckily, no risk here. For looping throught Infinity. Probably would end somewhat earlier due to some end of memory.

But still, it is possible to change length just like that. What will happen if we make it bigger?

var x = [9];
console.log(x); // [9]

x.length = 10;
console.log(x); // still [9], although length is 10 this time

// example from Red Mercury
x.forEach(function (item, index) {
    console.log('Item', index, item);
});
  
// will print: Item 0 9
  
// But...
do {
    console.log(x.shift());
} while(x.length > 0); // .shift() and .pop() update .length property

// will print 9 once, and nine times undefined
// probably the same with .pop(), just in reversed order

And the smaller?

var x = [9, 10, 14];
console.log(x); // [9, 10, 14]

x.length = 1;
console.log(x); // [9]

// example from Red Mercury
x.forEach(function (item, index) {
    console.log('Item', index, item);
  });
  
// will print: Item 0 9
  
// But...
do {
    console.log(x.shift());
} while(x.length > 0);

// will print only 9

So while bigger length can be checked with .forEach() the smaller cannot. It is not recommended to tamper with length value (because .forEach() and .shift() start to “desynchronize”), but in your own code this should not happen to you. I don’t think that language should be that totally bulletproof, nor that it’s possible. Reality will check it in the end with script breaking in a browser, and that could limit programmers too much. If JavaScript would have proper array, not just array like objects, that would be prevented but it is what it is.

Upvotes: 0

Barmar
Barmar

Reputation: 780724

That's not the only specification of the length property.

The specification of the abstract operation ArrayCreate(length, proto) says that the length property is initialized to the length parameter.

And the specification of Array Exotic Objects explains how it's updated:

Specifically, whenever an own property is added whose name is an array index, the value of the length property is changed, if necessary, to be one more than the numeric value of that array index

Other array manipulations are defined in terms of these operations, so the length property should accurately reflect the indexes of array elements.

Upvotes: 1

Red Mercury
Red Mercury

Reputation: 4300

What? Just use array.length. Im sure there exists no implementation of the standards that set the length of an array to positive infinity.

If for some reason you really want to avoid using array.length, just use forEach.

var arrLength = 0;
arr.forEach(function() {
  arrLength++
})

Upvotes: 1

Related Questions