JavaScript – 细微的myArray.forEach与for循环

我见过很多提示使用的问题:

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

代替:

 for (var i in myArray){ /* ... */ } 

对于数组,由于不一致的迭代( 请参阅此处 )。


但是,我似乎无法find任何似乎更喜欢面向对象的循环:

 myArray.forEach(function(item, index){ /* ... */ }); 

这对我来说似乎更直观。

对于我目前的项目,IE8的兼容性是重要的,我正在考虑使用Mozilla的polyfill ,但是我不是100%确定这将如何工作。

  • 循环标准(上面的第一个例子)和现代浏览器的Array.prototype.forEach实现有什么区别吗?
  • 现在的浏览器实现和Mozilla的实现有什么区别(特别是关于IE8)?
  • 性能不是一个问题,只是与哪些属性迭代的一致性。

for循环和forEach方法最大的区别在于, for前者,可能会break循环。 您可以通过简单地从传递给forEach的函数返回来模拟continue ,但是无法完全停止循环。

除此之外,两者实现了相同的function。 另一个微小的区别涉及for循环中的索引(和所有包含variables)的范围,由于variables提升。

 // 'i' is scoped to the containing function for (var i = 0; i < arr.length; i++) { ... } // 'i' is scoped to the internal function arr.forEach(function (el, i) { ... }); 

但是,我发现forEach更具performance力 – 它表示你的意图是遍历一个数组的每个元素,它提供了一个元素的引用,而不仅仅是索引。 总的来说,它主要归结为个人的品味,但是如果你可以使用forEach ,我会推荐使用它。


两个版本之间还有一些实质性的差异,特别是在性能方面。 事实上,简单的for循环比forEach方法执行得更好,正如这个jsperftesting所certificate的那样 。

这样的表演对你来说是否有必要由你来决定,而且在大多数情况下,我会更加青睐performance力。 这个速度差异可能是由于基本循环和稀疏matrix操作时的基本循环之间的小的语义差异,正如本答案所述 。

如果你不需要forEach的行为和/或你需要提前打破循环,你可以使用Lo-Dash的_.each作为替代,这也可以跨浏览器使用。 如果您使用的是jQuery,它也提供了一个类似的$.each ,只是注意在每个变体中传递给callback函数的参数的区别。

(至于for forEach polyfill,它应该可以在旧版浏览器中正常工作,而且不会出现任何问题,如果你select这样的路由。)

你可以使用你自定义的foreach函数,这将比Array.forEach更好

你应该添加一次到你的代码。 这将为Array添加新的function。

 function foreach(fn) { var arr = this; var len = arr.length; for(var i=0; i<len; ++i) { fn(arr[i], i); } } Object.defineProperty(Array.prototype, 'customForEach', { enumerable: false, value: foreach }); 

那么你可以在任何地方使用它像Array.forEach

 [1,2,3].customForEach(function(val, i){ }); 

唯一的区别是它快了3倍。 https://jsperf.com/native-arr-foreach-vs-custom-foreach

JSPerf

一些开发人员(如凯尔·辛普森)build议使用.forEach来表示该数组对纯函数有副作用和.mapfor这个方程中的循环,在我看来,作为一个通用的解决scheme适合这个方程,更容易沟通,因为它支持跨越多种语言,尤其是当迭代次数是预先计算的时候。