JavaScript属性是否在每次调用时计算?

JavaScript属性是否在每次调用时计算?,javascript,properties,Javascript,Properties,既然length是一个JavaScript属性,那么我是否使用 for( var i = 0; i < myArray.length; i++ ) for(var i=0;i

既然length是一个JavaScript属性,那么我是否使用

for( var i = 0; i < myArray.length; i++ )
for(var i=0;i

var myArrayLength=myArray.length;
对于(变量i=0;i
(变量i=0,iLen=myArray.length;i
for(var i = 0, iLen = myArray.length; i < iLen; i++)

有关各种Javascript循环构造的基准,请参阅。

如果myArray是Javascript数组,那么您不必担心它,它只是一个对象的属性查找,变量使用也是如此

如果OTH length是由浏览器DOM(特别是IE)提供的集合对象公开的属性,那么它可能会非常昂贵。因此,在枚举此类DOM提供的集合时,我倾向于使用:-

for (var i = 0, length = col.length; i < length; i++)
for(变量i=0,长度=col.length;i

但对于阵列,我不需要考虑这个问题。

不需要。它不会在调用时重新计算。它根据需要在数组类中重新计算

当您使用pushpopshiftunshiftconcatsplice等时,它会发生变化。否则,它只是一个数字——每次调用它的值时都是同一个实例


但是,只要不显式重写它(array.length=0),每次调用都会准确无误。

而第二种形式可能更快:

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

function p(f){var d1=new Date();for(var i=0;i每次调用时都不会计算length属性,但后一个版本会更快,因为您正在缓存属性查找。即使使用最新的JS实现(V8、TraceMonkey、SquirrelFish Extreme),使用高级(例如SmallTalk era;)属性缓存属性查找仍然比第二个版本多至少一个附加条件分支

但是Array.length不是常量,因为JS数组是可变的,所以推送、弹出、数组[Array.length]=0等都可能会改变它

还有其他一些概念,如DOM
NodeList
s,您可以通过调用
document.getElementsBySelector
获得这些概念,在这种情况下,可以在迭代时重新计算长度。但是,如果确实重新计算了长度,则很有可能它也实际发生了更改,因此手动计算输入输出可能无效。

根据,它只告诉如何计算“长度”属性,但不告诉何时计算。 我认为这可能取决于实现


如果我要实现它,我会按照指出的那样做,但是如果数组对象的“length”属性发生变化。

如果您认为它可能在循环过程中发生变化,那么当然应该为每个循环检查它

--否则,多次询问一个对象显然是愚蠢的,因为如果将它放在if语句的求值属性中

if(i=0, iMax=object.length; iMax>i; 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();
}
鉴于本守则:

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();
}

-J

对于数组来说,这两种方法之间的差异是可以忽略的。只有在处理DOM时,这一点才变得重要。访问局部变量不是属性访问——它是一种更快的直接查找,根据实现的不同,直接程度也不同。没有主要的实现(当然不包括IE)不再进行实际的属性查找。
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