我从书中学到,你应该这样写for循环:

for(var i=0, len=arr.length; i < len; i++){
    // blah blah
}

所以arr。每次不计算长度。

其他人说编译器会做一些优化,所以你可以这样写:

for(var i=0; i < arr.length; i++){
    // blah blah
}

我只是想知道在实践中哪种方法是最好的?


当前回答

现在是2017年。

我做了一些测试

https://jsperf.com/fastest-way-to-iterate-through-an-array/

看起来while方法在Chrome上是最快的。

看起来左边递减(——i)比Firefox上的其他递减(++i, i——,i++)快得多。

这种方法平均来说是最快的。但是它以相反的顺序迭代数组。

let i = array.length;
while (--i >= 0) {
    doSomething(array[i]);
}

如果前向顺序很重要,可以使用这种方法。

let ii = array.length;
let i = 0;
while (i < ii) {
    doSomething(array[i]);
    ++i;
}

其他回答

我已经尝试了一些其他方法来迭代一个巨大的数组,并发现将数组长度减半,然后在一个循环中迭代这两部分更快。这种性能差异可以在处理大型数组时看到。

var firstHalfLen =0;
var secondHalfLen = 0;
var count2=0;
var searchterm = "face";
var halfLen = arrayLength/2;
if(arrayLength%2==halfLen)
{
   firstHalfLen = Math.ceil(halfLen);
   secondHalfLen=Math.floor(halfLen);
}
else
{
   firstHalfLen=halfLen;
   secondHalfLen=halfLen;
}
for(var firstHalfCOunter=0,secondHalfCounter = arrayLength-secondHalfLen;
    firstHalfCOunter < firstHalfLen;
    firstHalfCOunter++)
{
  if(mainArray[firstHalfCOunter].search(new RegExp(searchterm, "i"))> -1)
  {
    count2+=1;
  }
  if(secondHalfCounter < arrayLength)
  {
    if(mainArray[secondHalfCounter].search(new RegExp(searchterm, "i"))> -1)
    {
        count2+=1;
    }
    secondHalfCounter++; 
  }
}

缓存长度for循环与上面的方法之间的一些性能比较(使用timer.js)。

http://jsfiddle.net/tejzpr/bbLgzxgo/

“最好”是指纯粹的表演吗?还是性能和可读性?

纯性能“最佳”是这个,它使用缓存和++前缀操作符(我的数据:http://jsperf.com/caching-array-length/189)

for (var i = 0, len = myArray.length; i < len; ++i) {
  // blah blah
}

我认为无缓存的for循环是执行时间和程序员读取时间的最佳平衡。每一个从C/ c++ /Java开始的程序员都不会浪费时间去阅读这本书

for(var i=0; i < arr.length; i++){
  // blah blah
}

另一个jsperf.com测试:http://jsperf.com/while-reverse-vs-for-cached-length

反向while循环似乎是最快的。唯一的问题是while(——i)将停止于0。我怎么能访问数组[0]在我的循环那么?

我总是用第一种体裁写作。

即使编译器足够智能,可以为数组优化它,但如果我们在这里使用DOMNodeList或一些计算长度的复杂对象,它仍然是智能的?

我知道关于数组的问题是什么,但我认为用一种风格编写所有循环是一个很好的实践。

虽然这是一个非常古老的问题,但也是一个非常有趣的问题,

请原谅我稍微改变一下这个问题,但我会在最后回答这个问题。

这个问题让我问自己,在js中是否有更好的循环方法:

所以我做了一些测试,以下是我的发现:

对于1000_000记录:最好是forEach。

对于100条记录:这根本不重要。


回到你刚才的问题:

我创建的例子和问题不完全一样。但我发现了一些有趣的事情:

首先,就像你说的,arr。如果它在比较语句I < arr内,Length每次都会计算。长度……

注意:下面的arrLength变量不超过1000_000条记录的数量。

例如:这不会工作

但是这个会

这需要0.036秒。与数字不变的情况相比,这是非常大的……


总之,

最好使用FOREACH

在你的例子中,i<arr。长度需要更多的时间(通常在1.3左右)

请参阅测试: 查看测试