Why should forEach be preferred over regular iterators?
我在看Airbnb javascript指南。有一个特别的声明,说:
Don’t use iterators. Prefer JavaScript’s higher-order functions instead of loops like for-in or for-of.
他们给出上述声明的原因是:
This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects.
我无法区分给出的两种编码实践:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const numbers = [1, 2, 3, 4, 5];
// bad
let sum = 0;
for (let num of numbers) {
sum += num;
}
sum === 15;
// good
let sum = 0;
numbers.forEach((num) => {
sum += num;
});
sum === 15; |
有人能解释一下,为什么forEach比常规的for循环更受欢迎?这真的有什么区别?使用常规的iterators有什么副作用吗?
airbnb风格指南中的推理适用于用于不可变的数组方法,即filter、map、reduce等,但不适用于forEach:
This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects.
所以比较起来更像是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // bad
let sum = 0;
for (let num of numbers) {
sum += num;
}
sum === 15;
// bad
let sum = 0;
numbers.forEach((num) => {
sum += num;
});
sum === 15;
// good
const sum = numbers.reduce((num, sum) => sum += num, 0);
sum === 15; |
一般情况下,for > forEach > for..of > for..in在性能方面。这种关系在几乎所有发动机中都是一致的,但可能因阵列长度不同而有所不同。
forEach是最新的Chrome/V8(基于此合成测试,几乎两次)中显著改进的一款:
- 我不明白开场白This reasoning in Airbnb style guide applies to array methods that are used for immutability, which are filter, map, reduce, etc. but not forEach:为什么foreach不能用于不可变?
- 它可以。但这并不是天生不变的。不会自动为您提供新的值(如reduce或map)。您改变了在其他地方定义的循环内的变量(示例中的sum)。您可以用同样的方法修改现有对象,从而打破"不变规则"(好吧,您也可以使用reduce这样做,但这通常被认为是一个错误)。for和foreach都是"坏"的,根据这个推理,foreach有一个函数的事实在这方面没有任何影响,因为我们不能返回这个函数的结果。
- 我认为这种推理是有效的(尽管通常更喜欢for..of的可读性),但不是他们得出的结论。github.com/airbnb/javascript迭代器和生成器这一章既矛盾又不一致。在一个地方,它表明应该避免副作用,然后他们在前臂内做副作用,并将其标记为"好"。记住,这只是风格指南。风格指南固执己见,并不总是有意义。
那没有道理。不应优先选择forEach。是的,使用map和reduce和filter比使用副作用操纵物体的循环要干净得多。
但是当你出于某种原因需要使用副作用时,那么for … in和for … of是惯用的循环结构。它们更容易阅读,速度也同样快,并强调你有一个带有副作用的循环体,与之相比,forEach在回调时看起来功能正常,但没有。与forEach相比,其他优点包括你可以使用const作为迭代元素,并且可以使用任意的控制结构(return和map。循环体中0)、continue、yield、await。
- N.B.Eric Lippert在c:blogs.msdn.microsoft.com/eric lippert/2009/05/18/…中对foreach与.ForEach(...)的描述基本相同,似乎Airbnb的人们正在陷入一个陷阱,认为看起来功能性更好的东西只是因为它看起来功能性更好。
大多数情况下,Airbnb StyleGuide都试图保持一致。这并不意味着永远没有理由使用for循环或for-in循环,比如假设您希望尽早跳出循环。
当使用for循环改变某个事物的值时,不变性就发挥了作用。例如,将数组缩减为整数,或者映射元素以生成新数组。使用内置的map、reduce或filter不会直接改变数组的值,因此它是首选的。在for/for in循环上使用forEach加强了在迭代器上使用高阶函数的样式一致性,因此我相信这就是推荐使用它的原因。
- 你能解释一下This isn't the same for forEach的说法吗?与其他方法(如map、reduce等)相比,foreach为什么会改变数组的值?
- foreach本身不会改变数组的值。我的意思是,与map或filter不同,foreach总是返回undefined,它没有返回值,可以用来改变数组(应该更清楚)。更新。
查看foreach和forloop的性能
只有为了可读性,我们使用foreach。除了循环之外,浏览器的兼容性、性能和本地感觉更受欢迎。
- 没有性能差异。
- 你给出的链接表明,foreach更快。
- "没有区别"—他说的是V8发动机。这就是区别。在Safari上,for始终比foreach快。
- @伯吉有区别。aik,对于>foreach>for..of>for..在性能方面,这在几乎所有发动机中都是一致的。仍然没有奇偶校验,您可以自己检查jspef.com/for-vs-foreach-vs-for-of。有趣的是,ForEach在最新的Chrome版本中得到了显著的改进。