一、语法
array.reduce(callbackfn, initialValue);
callbackfn =(accumulator, currentValue, currentIndex, array) => {
// 回调逻辑
}
callbackFn | 为数组中每个元素执行的函数。 其返回值将作为下一次调用 |
currentValue | 当前元素的值。 在第一次调用时,若指定了 |
currentIndex |
在第一次调用时,如果指定了 |
initialValue | 第一次调用回调时初始化 如果指定了 |
二、示例
1、打印所有参数
const numbers = [10, 20, 30];
numbers.reduce((acc, curr, idx, arr) => {
console.log({
accumulator: acc,
currentValue: curr,
currentIndex: idx,
array: arr,
});
return acc + curr; // 累加求和
}, 0);
{ accumulator: 0, // 初始值 currentValue: 10, // 第一个元素 currentIndex: 0, // 第一个索引 array: [10, 20, 30] // 原数组 } { accumulator: 10, // 上一轮返回值 (0 + 10) currentValue: 20, // 第二个元素 currentIndex: 1, // 第二个索引 array: [10, 20, 30] } { accumulator: 30, // 上一轮返回值 (10 + 20) currentValue: 30, // 第三个元素 currentIndex: 2, // 第三个索引 array: [10, 20, 30] }
最终返回值:
60
(10 + 20 + 30
)。
二、统计数组中每个元素的出现次数,并返回一个对象(键为元素值,值为出现次数)
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((allNames, name) => {
const currCount = allNames[name] ?? 0; // 获取当前名字的计数(若不存在则为 0)
return {
...allNames, // 复制原对象的所有属性
[name]: currCount + 1, // 更新当前名字的计数
};
}, {}); // 初始值为空对象 {}
第一轮
allNames = {}
(初始值)name = "Alice"
currCount = allNames["Alice"] ?? 0
→undefined ?? 0
→0
- 返回:
→
{ ...{}, "Alice": 0 + 1 }
{ "Alice": 1 }
第二轮
allNames = { "Alice": 1 }
name = "Bob"
currCount = allNames["Bob"] ?? 0
→undefined ?? 0
→0
- 返回:
→
{ ...{ "Alice": 1 }, "Bob": 0 + 1 }
{ "Alice": 1, "Bob": 1 }
第三轮
allNames = { "Alice": 1, "Bob": 1 }
name = "Tiff"
currCount = allNames["Tiff"] ?? 0
→undefined ?? 0
→0
- 返回:
→
{ ...{ "Alice": 1, "Bob": 1 }, "Tiff": 0 + 1 }
{ "Alice": 1, "Bob": 1, "Tiff": 1 }
第四轮
allNames = { "Alice": 1, "Bob": 1, "Tiff": 1 }
name = "Bruce"
currCount = allNames["Bruce"] ?? 0
→undefined ?? 0
→0
- 返回:
→
{ ...{ "Alice": 1, "Bob": 1, "Tiff": 1 }, "Bruce": 0 + 1 }
{ "Alice": 1, "Bob": 1, "Tiff": 1, "Bruce": 1 }
第五轮
allNames = { "Alice": 1, "Bob": 1, "Tiff": 1, "Bruce": 1 }
name = "Alice"
currCount = allNames["Alice"] ?? 0
→1 ?? 0
→1
- 返回:
→
{ ...{ "Alice": 1, "Bob": 1, "Tiff": 1, "Bruce": 1 }, "Alice": 1 + 1 }
{ "Alice": 2, "Bob": 1, "Tiff": 1, "Bruce": 1 }
最终结果
{ "Alice": 2, "Bob": 1, "Tiff": 1, "Bruce": 1 }
关键点
(1)如果左侧操作数为??
运算符(空值合并运算符)null
或undefined
,返回右侧操作数;否则返回左侧操作数。(2)在这里用于处理名字第一次出现时allNames[name]
为undefined
的情况。展开运算符
复制原对象的所有属性,避免直接修改原对象(保持不可变性)。...
动态键名
使用计算属性名语法,将变量[name]
name
的值作为对象的键。初始值
确保累加器从空对象开始,避免未定义行为。{}
的作用