Javascript减少陷阱-跳过第一次迭代?

JaT*_*aTo 3 javascript arrays reduce functional-programming

为什么javascript的减少第一次执行的跳过执行的实现?

[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
Run Code Online (Sandbox Code Playgroud)

我注意到第一条语句执行从未执行(在这种情况下,我希望有6个控制台日志,每个元素2个)。当我尝试在每次迭代中执行带有reduce的副作用的函数时,这是非常意外的行为。

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

为什么会发生这种情况,为什么JavaScript的本机Array的实现会减少呢?

=========================编辑1 /解决方案====================== ===
为了确保它经过第一次迭代,请给它一个初始值(在此情况下,第二个参数为此处/ 0)

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

wei*_*nda 5

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

这里直接,您可以看到

累加器累加回调的返回值;它是先前在回调的上一次调用中返回的累计值,或者如果提供的话,则返回initialValue(请参见下文)。


如果我们在这里查看源代码,我们可以看到其实现方式:

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;
};
Run Code Online (Sandbox Code Playgroud)

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

如果需要,可以回溯并检查输出。

  • 啊,是的,我现在明白了。如果我不希望它跳过第一次执行,则必须传递一个initialValue。谢谢! (3认同)