何时应使用forEach?

3

我可以选择:

var arr = [];

arr.forEach(function(i) {

     i;
});

for (var i = 0, length = arr.length; i < length; ++i) {

     arr[i];
}

什么时候使用其中一种而不是另一种,它们之间是否有性能差异?

2
forEach 操作比较慢,但它能够在每次迭代时创建一个作用域,而你通常需要在正常的 for 循环中手动进行设置。此外,使用 forEach 回调函数可以让您设置 this 的值(使用第二个参数)。然而,并不是所有浏览器都支持 forEach: http://kangax.github.io/es5-compat-table/#Array.prototype.forEach。另外需要注意的是,`forEach` 不会遍历空项目。更多信息,请参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach - 它还包括了一个用于不支持 forEach 的浏览器的 polyfill。 - Ian
这部分回答了你的问题:https://dev59.com/R2ox5IYBdhLWcg3wQSEO - vasanth
1
为了回答性能问题,请在http://jsperf.com/上创建一个性能测试,其中包含50,000个数组值或执行50,000个循环。 - LarsH
forEach 是符合 ECMAScript 5 的。 - Moritz Roessler
这是一个性能测试,结果在控制台中显示:http://jsfiddle.net/ssSt5/2/ - Tim Baas
1
@Tim 我看到一个片段有实时输出,而另一个没有 - 这可能会改变迭代所需的时间。你知道的 - 统计数据中有谎言,谎言中有更大的谎言,还有基准测试。 :) - Zsolt Szilagyi
1个回答

10

当你使用foreach时:

  • 你的数组是关联数组或者存在间隙,也就是说你不能通过递增的数字(1、2、5、'x'、-7)来访问每一个元素
  • 你需要按照数组中出现的顺序循环迭代(如2、1、3)
  • 你想要确保不会进入无限循环

最后一点是主要区别:foreach操作的是副本,因此即使更改了元素,数组仍然保持完好无损,并且可以进行迭代而没有缺陷。

这个副本使得foreach比for略慢,因为它需要复制数据。请记住,一些旧的或罕见的浏览器不支持foreach,但它们支持“for”。除非你的数组非常大(10,000+项),否则忽略速度差异。它只有几毫秒。

当你使用for时:

  • 你想要一种简单的方法来改变正在移动的数组
  • 你想要特定的序列,例如for($i=100;$i<1000;$i+=5),结果为100、105、110...

我已经构建了一个游戏引擎,并尝试尽可能提高其速度。我想将它们更改为for循环只能是一件好事,因为这样做更快,使我的引擎更兼容,对吧? - user2251919
如果你的数组是连续编号的,并且你有避免意外无限循环的知识,那么可以。但是,不要高估这种差异。 :) - Zsolt Szilagyi
好的,谢谢。我会牢记这个的。我想现在还是放一放吧,但是了解这个还是很有好处的 :) - user2251919
1
"你的数组是关联数组": 你绝不能在数组中使用非数字属性。它们甚至不会被forEach视为数组元素。负索引也不被考虑。"foreach在副本上工作": 这是不正确的(或者至少是一种实现细节)。只有元素的范围是固定的。如果在迭代之前修改了数组的值,回调将得到新值。请参见http://es5.github.io/#x15.4.4.18。你从哪里得到它是在副本上工作的信息? - Felix Kling
1
你需要按照数组中元素出现的顺序进行迭代。你也可以使用for循环来实现。总体而言,我认为你的答案包含了一些不准确的信息,特别是关于复制的事情。规范已经非常清楚地说明了如何处理修改。 - Felix Kling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接