问题
In JS are the lengths of an array cached or does it depend on the different engines/browsers?
Normally I'd assume that browsers' JS engines are pretty dumb and cache the length of arrays, for example:
var a = [ ];
var l = l;
function arrayPush(i)
{
l = a.push( i );
}
function arrayPop()
{
var r = a.pop();
l = a.length;
return r;
}
(as a brief example, of course it'll be silly to replicate every array function but if it speeds stuff up it then it's worth it)
回答1:
The array length is cached. It is updated each time the array is manipulated.
When you invoke the .push() method on the array, the array length is updated in step 6 of the algorithm:
Call the [[Put]] internal method of O with arguments "length", n, and true.
Source: http://es5.github.com/x15.4.html#x15.4.4.7
When you invoke the .pop() method of an array, the array length is updated in step 5.d of the algorithm:
Call the [[Put]] internal method of O with arguments "length", indx, and true.
Source: http://es5.github.com/x15.4.html#x15.4.4.6
When you assign a value to the array at an given index, the [[DefineOwnProperty]] internal method is invoked. The array length is updated in step 4.e.ii of the algorithm:
Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", oldLenDesc, and false as arguments. This call will always return true.
Source: http://es5.github.com/x15.4.html#x15.4.5.1
回答2:
As elaborated on in this answer, modern browsers will have JS engines that will handle Array.length quite sensibly.
If you're worried about its performance on lesser JS engines, you can cache it if it's going to be used repeatedly e.g. when used in the stopping condition of a loop.
for (var i = 0, arrLength = arr.length; i < arrLength; i++) { }
It's unlikely that it will be SO slow that you need to maintain your own value for length (as in your example). That's unlikely to give you any noticeable performance gains, but will make your code less maintainable and more vulnerable to bugs.
回答3:
It depends on the implementation, though a sane browser should simply maintain a counter. If it's a very poor implementation, it'll probably have to traverse a data structure or something to get the size.
Normally you'd do something like this:
add(obj)
{
buffer[ptr++] = obj;
}
getLength()
{
return ptr;
}
When the buffer is empty, ptr is 0. Adding an object inserts it into buffer[0] and increments ptr by one, which will return 1 for the length, too. This means there's no need to do any form of "count" operation when you want the length.
来源:https://stackoverflow.com/questions/8166947/is-the-length-of-an-array-cached