在JavaScript中,字符串/数组.length属性是否进行任何处理?

时间:2011-09-15 03:27:47

标签: javascript

当迭代字符串或数组(或其他任何带有length属性的东西)时,我总是使用这样的循环:

var foo = [...];
var i;
for(i=0; i<foo.length; i++) {
    // do something
}

但是,我刚刚遇到了这样做的人:

var foo = [...];
var fooLen = foo.length;
var i;
for(i=0; i<fooLen; i++) {
    // do something
}

他说他认为“.length”正在重新计算长度,因此循环会反复重新计算字符串/数组的长度,因此通过将其长度保存到变量,它将更加优化。

我总是假设长度只是一个值属性,因为它的使用方式(它不是"asdf".length(),它是"asdf".length)但是不是这样吗?

4 个答案:

答案 0 :(得分:3)

在某些情况下,将长度放入局部变量比访问.length属性更快,并且它因浏览器而异。在SO和许多jsperf测试中已经就此进行了性能讨论。在现代浏览器中,差异并不像我想象的那么多,但在某些情况下它们确实存在(我似乎无法找到那些先前的线程)。

还有不同类型的对象可能具有不同的性能特征。例如,javascript数组可能具有与从getElementsByClassName()等某些DOM函数返回的类数组对象不同的性能特征。

并且,在某些情况下,您可能会在数组的末尾添加项目,并且不希望迭代您添加的项目,因此您可以在开始之前获得长度。

答案 1 :(得分:1)

来自MDC

for (var i = 0; i < a.length; i++) {  
    // Do something with a[i]  
}  
  

当您查找length属性时,这效率稍低   每一次循环。这是一个改进:

for (var i = 0, len = a.length; i < len; i++) {  
    // Do something with a[i]  
} 

答案 2 :(得分:0)

对于“常规”数组可能没什么区别,但对于像“node.children.length”这样的东西,我会在安全方面犯错,只调用一次。 CoffeeScript会自动为您完成。

请注意,如果长度可以在循环期间发生变化,则行为会有实际差异。

答案 3 :(得分:0)

这取决于你是否改变了foo的长度。

var foo = [1,2,3];
  while(foo.length){
  foo.shift();
}

显然代码是跟踪foo的长度,而不仅仅是记住一个值。

您可以在循环中将长度指定为数字。

for(i=0, L=foo.length;i<L; i++) {
    // do something to foo[i]
}