要跳过第一次迭代吗?

人气:942 发布:2022-10-16 标签: javascript arrays functional-programming reduce

问题描述

为什么在第一次迭代时,Java脚本的Reducer实现会跳过执行?

[1,2,3].reduce((acc, val) => {
    console.log('acc',acc);
    console.log('val',val)
    return acc + val;
});
// acc 1
// val 2
// acc 3
// val 3
// 6

我注意到第一条语句的执行从不运行(在本例中,我本以为会有6个控制台日志,每个元素2个)。当我尝试在每个迭代中使用REDUTE执行有副作用的函数时,这是非常意外的行为。

在我使用过的其他语言中,传递的列表的每个迭代都会执行。还有别的例子吗?

为什么会发生这种情况?为什么Java脚本的原生数组的实现会这样减少?

= 要确保它通过第一次迭代,请给它一个初始值(本例中的第二个参数/0)

[1,2,3].reduce((acc, val) => { console.log('acc',acc); console.log('val',val) return acc + val; }, 0);

推荐答案

这是因为在每次迭代时,第一个值被视为return值(或累加器)。

直接从here可以看到

累加器累加回调的返回值;它是 的最后一次调用中返回的累加值。 回调或InitialValue(如果提供)(见下文)。

如果我们查看源代码here,我们可以看到它是如何实现的:

Array.prototype.myReduce = function(callback, initialVal) {
    var accumulator = (initialVal === undefined) ? undefined : initialVal;
    for (var i = 0; i < this.length; i++) {
        if (accumulator !== undefined)
            accumulator = callback.call(undefined, accumulator, this[i], i, this);
        else
            accumulator = this[i];
    }
    return accumulator;
};

else结构中,我们可以看到,如果值是undefined,我们将其设置为数组中的i-th子索引;对于第一次迭代,这是第一个子索引。之后,它将成为后续迭代的回调(返回)值。

如果您愿意,可以回溯并检查输出。

910