Reputation: 365
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
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
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
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