TypeError: Reduce of empty array with no initial value
JavaScript 异常 "reduce of empty array with no initial value" 发生在使用了 reduce 函数时。
消息
TypeError: Reduce of empty array with no initial value (V8-based & Firefox & Safari)
错误类型
TypeError
哪里出错了?
在 JavaScript 中,有几个 reduce 函数:
Array.prototype.reduce(),Array.prototype.reduceRight()和TypedArray.prototype.reduce(),TypedArray.prototype.reduceRight())。
这些函数可选地接受一个 initialValue(它将作为 callback 第一次调用的第一个参数)。但是,如果未提供初始值,它将使用 Array 或 TypedArray 的第一个元素作为初始值。当提供空数组时会引发此错误,因为在这种情况下无法返回初始值。
示例
无效案例
当与 filter(Array.prototype.filter(), TypedArray.prototype.filter())结合使用时,此问题经常出现,filter 会删除列表中的所有元素。因此,没有元素可用作初始值。
js
const ints = [0, -1, -2, -3, -4, -5];
ints
.filter((x) => x > 0) // removes all elements
.reduce((x, y) => x + y); // no more elements to use for the initial value.
同样,如果选择器中有拼写错误,或者列表中元素的数量出乎意料,也可能发生同样的问题。
js
const names = document.getElementsByClassName("names");
const name_list = Array.prototype.reduce.call(
names,
(acc, name) => `${acc}, ${name}`,
);
有效情况
这些问题可以通过两种不同的方式解决。
一种方法是实际提供一个 initialValue 作为操作符的“中性元素”,例如加法的 0,乘法的 1,或连接的空字符串。
js
const ints = [0, -1, -2, -3, -4, -5];
ints
.filter((x) => x > 0) // removes all elements
.reduce((x, y) => x + y, 0); // the initial value is the neutral element of the addition
另一种方法是处理空情况,可以在调用 reduce 之前,或者在添加一个意外的虚拟初始值后在回调中处理。
js
const names = document.getElementsByClassName("names");
let nameList1 = "";
if (names.length >= 1) {
nameList1 = Array.prototype.reduce.call(
names,
(acc, name) => `${acc}, ${name}`,
);
}
// nameList1 === "" when names is empty.
const nameList2 = Array.prototype.reduce.call(
names,
(acc, name) => {
if (acc === "")
// initial value
return name;
return `${acc}, ${name}`;
},
"",
);
// nameList2 === "" when names is empty.