关于javascript:为什么forEach优先于常规迭代器?

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风格指南中的推理适用于用于不可变的数组方法,即filtermapreduce等,但不适用于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(基于此合成测试,几乎两次)中显著改进的一款:

></P><P><img src=


那没有道理。不应优先选择forEach。是的,使用mapreducefilter比使用副作用操纵物体的循环要干净得多。

但是当你出于某种原因需要使用副作用时,那么for … infor … of是惯用的循环结构。它们更容易阅读,速度也同样快,并强调你有一个带有副作用的循环体,与之相比,forEach在回调时看起来功能正常,但没有。与forEach相比,其他优点包括你可以使用const作为迭代元素,并且可以使用任意的控制结构(returnmap。循环体中0)、continueyieldawait


大多数情况下,Airbnb StyleGuide都试图保持一致。这并不意味着永远没有理由使用for循环或for-in循环,比如假设您希望尽早跳出循环。

当使用for循环改变某个事物的值时,不变性就发挥了作用。例如,将数组缩减为整数,或者映射元素以生成新数组。使用内置的mapreducefilter不会直接改变数组的值,因此它是首选的。在for/for in循环上使用forEach加强了在迭代器上使用高阶函数的样式一致性,因此我相信这就是推荐使用它的原因。


查看foreach和forloop的性能

只有为了可读性,我们使用foreach。除了循环之外,浏览器的兼容性、性能和本地感觉更受欢迎。