由于length是JavaScript属性,所以我是否使用重要吗
for( var i = 0; i < myArray.length; i++ )
或
var myArrayLength = myArray.length;
for( var i = 0; i < myArrayLength ; i++ )
for(var i = 0, iLen = myArray.length; i < iLen; i++)
请参阅http://blogs.oracle.com/greimer/resource/loop-test.html用于各种Javascript循环结构的基准测试。
如果myArray是javascript数组,那么您不必担心它,它只是对象上的一个属性查找,但变量用法也是如此。
如果OTH长度是由浏览器DOM(尤其是IE)提供的集合对象公开的属性,那么它可能会非常昂贵。因此,当枚举这样一个DOM提供的集合时,我倾向于使用:-
for (var i = 0, length = col.length; i < length; i++)
但对于数组,我并不在意。
我认为你的问题的意图的答案是,是的,如果你在循环中修改数组,那么array.length属性在每次迭代中都会重新计算。例如,以下代码:
var arr = [1,2,3];
for(var i = 0; i < arr.length; i++){
console.debug("i = " + i);
console.debug("indexed value = " + arr[i])
arr.pop();
}
将输出:
i = 0
indexed value = 1
i = 1
indexed value = 2
而这个代码:
var arr = [1,2,3];
var l = arr.length;
for(var i = 0; i < l; i++){
console.debug("i = " + i);
console.debug("indexed value = " + arr[i])
arr.pop();
}
将输出:
i = 0
indexed value = 1
i = 1
indexed value = 2
i = 2
indexed value = undefined
-J
否。它不会在调用时重新计算。它在Array类中根据需要重新计算。
当您使用push、pop,shift和unshift时,它会发生变化。否则,它只是一个数字——每次调用它的值时都是相同的实例。
但是,只要不显式重写它(array.length=0),每次调用都是准确的。
不是每次调用都计算length属性,但在缓存属性查找时,后一个版本会更快。即使是最新的JS实现(V8、TraceMonkey、SquirrelFish Extreme)使用高级(例如SmallTalk era;))属性缓存,属性查找仍然比第二个版本多至少一个额外的条件分支。
然而,Array.length并不是恒定的,因为JS数组是可变的,所以push, pop, array[array.length]=0, etc
可能都会改变它
还有其他一些概念,比如您从document.getElementsBySelector
之类的调用中获得的DOM NodeList
,这些概念应该是活动的,在这种情况下,可以在迭代时重新计算长度。但是,如果确实重新计算了长度,那么很有可能它也会发生实际更改,因此手动缓存输出可能无效。
虽然第二种形式可能更快:
function p(f) { var d1=new Date(); for(var i=0;i<20;i++) f(); print(new Date()-d1) }
p(function(){for(var i=0;i<1000000; i++) ;})
p(function(){var a = new Array(1000000); for(var i=0;i<a.length; i++) ;})
> 823
> 1283
在任何非边缘情况下,这都不重要。
如果你认为它可能在循环过程中发生变化,那么当然应该检查每个循环。。。
--否则,多次询问一个对象显然是疯了,因为如果你把它放在if语句的求值属性中。。。
if(i=0, iMax=object.length; iMax>i; i++)
--只有在特殊情况下,你才应该考虑采取其他方式!-)
根据ECMAScript规范,它只是告诉应该如何计算"长度"属性,但它没有告诉何时计算。我认为这可能取决于实施。
如果我要实现它,我会按照Jonathan指出的那样做,但如果是Array对象的"length"属性。