reduce是JavaScript数组聚合最核心灵活的方法,通过一次遍历将数组折叠为单个值,关键在于正确设置累加器初始值并避免副作用。

JavaScript 的 reduce 方法是处理数组聚合最核心、最灵活的工具,它通过一次遍历,将数组“折叠”为单个值——比如求和、计数、分组、扁平化、对象合并等。关键在于理解它的执行逻辑和正确设置累加器(accumulator)的初始值。
reduce 的基本结构与参数含义
reduce 接收两个主要参数:一个回调函数(reducer),和一个可选的初始值(initialValue)。回调函数本身有四个参数:累加器(acc)、当前项(curr)、当前索引(index)、原数组(arr),但常用前两个。
若未传初始值,reduce 会默认用数组第一个元素作为初始累加器,从第二个元素开始遍历;若传了初始值,则从第一个元素开始处理。这点极易出错,尤其当数组为空时——没初始值会直接报错。
- 空数组调用
reduce且无初始值 → 报错Reduce of empty array with no initial value - 建议:只要逻辑允许,显式传入初始值,提升健壮性
- 累加器类型可以是任意值(数字、字符串、对象、数组等),取决于你要聚合的目标形态
常见聚合场景与写法示例
聚合不只限于加法。关键是让累加器在每次迭代中“承载并更新”所需状态。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
-
求和:
[1,2,3].reduce((sum, n) => sum + n, 0) -
找最大值:
[4,2,9,1].reduce((max, n) => n > max ? n : max, -Infinity) -
统计频次(转为对象):
['a','b','a'].reduce((obj, item) => ({ ...obj, [item]: (obj[item] || 0) + 1 }), {}) -
按属性分组:
list.reduce((groups, item) => { (groups[item.type] ||= []).push(item); return groups; }, {})
避免常见陷阱
reduce 强大但容易写出副作用或低效代码。
- 不要在 reducer 内部修改外部变量或原数组(如
push到外部数组),这破坏纯函数特性,也容易引发意外行为 - 避免在每次迭代中展开大对象(如
{...acc, [k]: v})——浅拷贝成本高,大数据量时性能明显下降;可用Object.assign或直接赋值(如acc[key] = value)替代 - 注意初始值类型必须与累加器期望类型一致,比如想返回对象却传
0做初始值,后续acc.xxx就会undefined
替代方案与何时考虑不用 reduce
不是所有聚合都非得用 reduce。可读性和维护性更重要。
- 简单求和/乘积/拼接 →
reduce合适;但若只是arr.join(''),直接用join更清晰 - 需要中途退出(如找到首个满足条件的值后停止)→
some/find比reduce更语义明确 - 要同时做多个聚合(如一边求和一边计数)→ 可用
reduce返回对象,但有时拆成两个forEach或用for循环反而更直观

















