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

标签 javascript arrays functional-programming reduce

为什么javascript的reduce实现会在第一次迭代时跳过执行?

[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 reduce的实现是这样的?

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

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

最佳答案

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

直接来自 here , 你可以看到

The accumulator accumulates the callback's return values; it is the accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied (see below).


如果我们查看源代码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中的子索引大批;对于第一次迭代,这是第一个。之后,它成为后续迭代的回调(返回)值。

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

关于Javascript 减少陷阱 - 跳过第一次迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52245352/

相关文章:

javascript - 如何在 HTML 元素中显示和隐藏数组的每个项目?

arrays - 如何使用 OmniThreadLibrary 中的 SetParameter 将数组作为参数传递给任务?

python - 从 Python 中的协程产生一个值,也就是将回调转换为生成器

javascript - 将 JQuery-UI 可排序连接列表自定义配置保存到本地 Cookie

javascript - 在鼠标进入/离开时展开和折叠导航,REACT

javascript - C3JS加载函数和点值

javascript - 将 D3js 树中 Json 对象的叶子 Node 转换为 Child 下的子 Node

c++ - 使用绝对元素编号访问二维数组的元素

R:在函数参数中为一般(通用)使用的函数指定变量名

recursion - 在 Clojure 中将结果累积到向量中的最佳方法? (纯功能代码看起来丑陋和冗长)