为什么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
我注意到第一条语句执行从未执行(在这种情况下,我希望有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);
答案 0 :(得分:5)
这是因为在每次迭代中,第一个值都被视为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
子索引;对于第一次迭代,它是第一个。之后,它将成为后续迭代的回调(返回)值。
如果需要,可以回溯并检查输出。