Javascript效率:'for'vs'forEach'

ton*_*ins 78 javascript foreach loops for-loop

2017年Javascript中使用for()循环与.forEach的当前标准是什么.

我目前的工作我的方式,通过柯尔特史蒂尔斯的"Web开发训练营"在Udemy他热衷forEachfor他的教导.然而,我在练习期间搜索了各种各样的东西,作为课程工作的一部分,我发现越来越多的建议使用for-loop而不是forEach.大多数人似乎都认为for循环更有效率.

这是自课程编写以来发生过变化的事情(大约在2015年),或者是每个人的真正优点和缺点,哪个人将学习更多经验.

任何建议将不胜感激.

vol*_*ron 154

对于

for循环效率更高.它是一个循环结构,专门设计用于在条件为真时进行迭代,同时提供步进机制(通常用于增加迭代器).例:

for (var i=0, n=arr.length; i < n; ++i ) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

这并不是说for -loops总是会更高效,只是JS引擎和浏览器已经优化了它们.多年来,关于哪个循环结构更有效(for,while,reduce,reverse-while等)已经存在妥协 - 不同的浏览器和JS引擎有自己的实现,提供不同的方法来产生相同的结果.随着浏览器进一步优化以满足性能需求,理论上[].forEach可以以更快或与a相当的方式实现for.

优点:

  • 高效
  • 早期循环终止(荣誉breakcontinue)
  • 条件控制(i<n可以是任何东西而不是绑定到数组的大小)
  • 变量作用域(循环结束后可用的var i叶子i)

的forEach

.forEach是主要遍历数组的方法(也可以是其他可枚举的方法,例如MapSet对象).它们更新,并提供主观上更容易阅读的代码.例:

[].forEach((val, index)=>{
   ...
});
Run Code Online (Sandbox Code Playgroud)

优点:

  • 不涉及变量设置(遍历数组的每个元素)
  • functions/arrow-functions将变量范围限定为块
    在上面的示例中,val将是新创建的函数的参数.因此,val在循环之前调用的任何变量都会在结束后保存它们的值.
  • 主观上更易于维护,因为它可能更容易识别代码正在做什么 - 它迭代可枚举; 而for循环可用于任何数量的循环方案

性能

性能是一个棘手的主题,通常需要一些经验,当涉及到预先考虑或方法.为了提前确定(在开发过程中)可能需要多少优化,程序员必须很好地了解过去的问题案例经验,以及对潜在解决方案的良好理解.

在某些情况下使用jQuery有时可能太慢(有经验的开发人员可能知道),而其他时间可能不是问题,在这种情况下,库的跨浏览器合规性和易于执行其他功能(例如,AJAX,事件处理)值得节省开发(和维护)时间.

另一个例子是,如果性能和优化是一切,那么就没有其他代码而不是机器或组件.显然情况并非如此,因为有许多不同的高级和低级语言,每种语言都有自己的权衡.这些权衡包括但不限于专业化,开发简便性和速度,维护简便性和速度,优化代码,无错误代码等.

途径

如果您对某些内容需要优化代码没有很好的理解,那么首先编写可维护代码通常是一个很好的经验法则.从那里,您可以测试并确定需要时需要更多关注的内容.

也就是说,某些明显的优化应该是一般实践的一部分,不需要任何思考.例如,考虑以下循环:

for (var i=0; i < arr.length; ++i ){}
Run Code Online (Sandbox Code Playgroud)

对于循环的每次迭代,JavaScript都会检索arr.length每个循环的键查找成本核算操作.没有理由不这样做:

for (var i=0, n=arr.length; i < n; ++i){}
Run Code Online (Sandbox Code Playgroud)

这也是一样的,但只检索arr.length一次,缓存变量并优化代码.

  • 优秀,彻底,非放肆的答案,不受单个时间点,实施或微基准测试的约束. (11认同)
  • for 循环在调试方面通常具有优势:它们很容易进入、断点和检查。使用 forEach() 额外的回调级别会使事情变得有点复杂。 (4认同)
  • 我要补充的是,这个答案可以使用一些更正更新或附录。例如,现在许多浏览器在内部优化为字节码,因此如果满足某些条件,就会执行一次重复操作。我认为如果数组在循环体中未受影响,那么它只会检索一次“arr.length”。我欢迎有更熟悉的人参与进来。 (4认同)
  • 我真的很喜欢这个答案和短语[[...],如果性能和优化就是一切,那么除了机器或程序集,别无其他代码。我相信使用`let`声明来声明块作用域局部变量,除非在不支持`let`的环境中,`forEach`的第二个优点不再是优于`for`循环的优点。 (3认同)
  • 我不认为这段代码`for (var i=0, n=arr.length; i &lt; n; ++i){}`会比这个`for (var i=0; i &lt; arr .length; ++i){}`。事实上,Js引擎并不计算数组元素。它只是从“length”属性中获取数字,而不从头开始计算所有数组元素。 (3认同)
  • 我通常使用 for 循环,但我注意到 forEach 的优点是它可以作为一行代码工作,这在 Web 控制台中很有用,例如摆脱烦人的元素: `document.querySelectorAll(".someClassName" ).forEach(function(el){el.remove()})` (3认同)
  • 很好的答案,但是“Array.prototype.length”的概念是错误的,不会被计算,这里有一篇文章解释它https://dmitripavlutin.com/the-magic-behind-array-length-property/ (2认同)
  • @Microsis 这里没有理由,当时可能是微优化,但这是不可避免要改变的浏览器/引擎选择。由于它们位于示例中,因此它们是等效的。有时,在我的示例中,我尝试展示一种稍微不同的使用语法的方式来让新手思考。人们经常看到“i++”,但是“++i”引起了人们的注意,并导致人们发现 for 循环的最后部分是一个表达式,它可以用于许多操作,而不仅仅是设置循环增量。 (2认同)
  • for循环的另一个优点是向后迭代而不需要反转数据 (2认同)