reduce函数没有将累加器初始化为零?

时间:2018-09-27 12:24:51

标签: javascript ecmascript-6 reduce

reduce不会将累加器初始化为零吗?因为发生以下示例,所以我无法理解。

const r = (acc, curr) => acc |= (1 << curr);

let x;
x |= (1 << 0);

console.log(x); // -> 1 - OK
console.log([0].reduce(r)); // -> 0 - ???

以及如何像我期望的那样正确获得 1 而不进行类似[0, 0].reduces(r);的操作。

1 个答案:

答案 0 :(得分:3)

否,reduce没有默认累加器。当您仅使用一个参数(回调)调用reduce时,它对回调进行的第一次调用将第一个条目用作累加器,将第二个条目用作“添加”到其的值。当然,只有在数组具有至少两个条目时,它才能这样做。当数组中只有一个条目并且您没有提供累加器默认值时,该条目的值是reduce的结果(并且根本不会调用您的回调)。这就是console.log([0].reduce(r));给您0的原因。最后,如果您在一个空数组上调用reduce而不提供默认值,那就是一个错误。 (这就是a.reduce((a, b) => a + b)a.reduce((a, b) => a + b, 0) 是同一件事的原因。)

示例:

// Outputs 1 without calling the callback
console.log([1].reduce((acc, value) => {
    console.log(`acc = ${acc}, value = ${value}`);
    return acc + value;
}));
// Outputs 3 after calling the callback with acc = 1 and value = 2
console.log([1, 2].reduce((acc, value) => {
    console.log(`acc = ${acc}, value = ${value}`);
    return acc + value;
}));

let a = [];
// Throws an error
try {
    console.log(a.reduce((a, b) => a + b));
} catch (error) {
    console.error(error);
}
// Works
try {
    console.log(a.reduce((a, b) => a + b, 0));
} catch (error) {
    console.error(error);
}
.as-console-wrapper {
    max-height: 100% !important;
}