`reduce` 究竟要不要用?到底什么时候才“值得”用?

👋 前言

在日常前端开发中,mapfilterforEach 我们都用得顺手,但一提到 reduce,很多人马上露出"🤯懵"的表情。虽然 reduce 看起来像是"现代高级语法",但它其实早在 ES5(2009 年)就已经诞生了。

那一年,你可能还在用 IE8,但 reduce 已经在等你了 😎

我们常听到两种极端的说法:

  • "reduce 太高级了,看不懂就别用。"
  • "你这能用 reduce,干嘛还写 forEach,显得不专业。"

那么问题来了:到底什么时候我们真的"需要" reduce?它的优势到底是什么?

🧩 一句话解释:reduce 是"归并器"

reduce 的作用是:把一个数组变成一个值(这个值可以是数字、对象、数组、字符串......都可以)。

举个简单例子:

js 复制代码
const nums = [1, 2, 3];
const sum = nums.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 6

没错,它可以"累加"。但 reduce 远不止加法那么简单。

🚀 用 reduce 可以做什么?

使用场景 示例 用不用 reduce
求和 数组求和 ✅ 非常合适
统计 单词出现次数统计 ✅ 高效
结构变换 数组转对象、转 Map ✅ 优雅
嵌套结构处理 二维数组扁平化、树结构构建 ✅ 函数式利器
简单遍历 单纯执行函数(无返回值) ❌ 用 forEach 更合适
多条件过滤 保留某些元素 ❌ 用 filter 更直接

🧠 举几个"值得用"的例子

✅ 1. 把数组变成对象(索引表)

js 复制代码
const list = [
  { id: 'a1', name: '张三' },
  { id: 'b2', name: '李四' },
];

const map = list.reduce((acc, item) => {
  acc[item.id] = item.name;
  return acc;
}, {});

console.log(map);
// 👉 { a1: '张三', b2: '李四' }

比起先 forEach 然后一个个 map[item.id] = ...reduce 一步到位,清晰干净。

✅ 2. 分组统计

js 复制代码
const items = [
  { type: 'A', count: 1 },
  { type: 'B', count: 2 },
  { type: 'A', count: 3 },
];

const grouped = items.reduce((acc, item) => {
  acc[item.type] = (acc[item.type] || 0) + item.count;
  return acc;
}, {});

console.log(grouped);
// 👉 { A: 4, B: 2 }

很难用 mapfilter 做得更清楚,这种"合并累加"的需求,reduce 天生就适合。

✅ 3. 复杂嵌套数据处理

比如后端返回了一堆数据,要按 tab 分类:

js 复制代码
const data = [
  { tab: 'A', value: 1 },
  { tab: 'B', value: 2 },
  { tab: 'A', value: 3 },
];

const tabMap = data.reduce((acc, item) => {
  if (!acc[item.tab]) acc[item.tab] = [];
  acc[item.tab].push(item.value);
  return acc;
}, {});

得到:

css 复制代码
{
  A: [1, 3],
  B: [2]
}

😵 为什么有些人觉得 reduce 很难用?

  • 它"抽象"太强,acc 是什么?cur 是谁?初始值又是啥?
  • 很多时候,只是为了"副作用"用它(比如 acc[x] = ...),反而不如 forEach 来得直观
  • ESLint 常提示 no-param-reassign,让初学者更混乱

🎯 那到底什么时候该用 reduce

总结一句话:

✅ 当你需要把一个数组"转化 "为一个值/对象/结构时,推荐用 reduce

❌ 如果只是遍历数组执行操作,不推荐用 reduce,用 forEach 更好

❌ 什么时候不要硬上 reduce

情况 1:只是单纯做副作用(比如设置值)

js 复制代码
// ❌ 没必要用 reduce
arr.reduce((_, item) => {
  doSomething(item);
}, null);

// ✅ 应该用 forEach
arr.forEach(item => doSomething(item));

情况 2:代码变得难以阅读

如果你要解释 3 层嵌套的 reduce 才能让别人理解,那就说明它不该用 reduce,哪怕它写起来少几行。

🧘 小结

项目 推荐用 reduce 吗? 理由
数组求和 / 累加 函数式最简洁
按条件聚合 精准聚合逻辑
数据结构变换(如数组转对象) 直观可读
扁平化 / 转树结构 表达能力强
执行副作用操作(不返回值) 用 forEach 更清楚
只是过滤 用 filter 简单直接

📘 reduce 这个名字是怎么来的?它英文到底什么意思?

有时候我们学一个 API,会忍不住问:

"为什么叫它 reduce?不是叫 sumUpcombinefold 呢?"

其实它确实是有语义基础的。

reduce 是英文中的动词,意思是:

"to make something smaller or simpler"

------「使某物减少、缩小、简化」

🔤 常见的英文用法举例:

  • reduce noise 👉 降噪
  • reduce cost 👉 降低成本
  • reduce weight 👉 减肥
  • reduce a problem to its essence 👉 把问题简化成本质

🧠 在 JavaScript 中,reduce 就是这个含义的编程表达:

js 复制代码
[1, 2, 3, 4] → 10      // 数字
[1, 2, 3]    → {1: true, 2: true, 3: true}  // 对象

也就是说:

reduce 是把"一堆数据"归约成"一个值",

是从"多个" → "一个"的过程,是一种简化、压缩、归纳

✅ 英文语义与代码行为对照:

英文语境 编程中的含义
reduce noise 清洗、精简数据
reduce cost 减少资源或运行消耗
reduce complexity 简化代码结构
reduce (数组) 将数组转化为一个目标结构

所以这个 API 不是随便起名的,它的语义就是 "压缩"、"归并"、"总结"!

🧪 最后,给你一个面试/练手题

reduce 实现一个函数,把数组 [1, 2, 3, 4] 转成 { 1: true, 2: true, 3: true, 4: true }

总结

reduce 是一个很强大的工具,但不是什么都要 reduce

当你真正"需要把数组折叠成一个结构 "时,reduce 能让你写出 少但更强的代码

如果你觉得这篇文章对你有帮助,别忘了点赞 + 收藏

欢迎关注我,我会持续分享实战中的高质量前端知识!

相关推荐
程序视点4 分钟前
如何高效率使用 Cursor ?
前端·后端·cursor
前端领航者5 分钟前
重学Vue3《 v-for的key属性:性能差异与最佳实践》
前端·javascript
归于尽5 分钟前
跨域问题从青铜到王者:JSONP、CORS原理详解与实战(前端必会)
前端·浏览器
Andy_GF17 分钟前
纯血鸿蒙HarmonyOS Next 远程测试包分发
前端·ios·harmonyos
岁忧30 分钟前
(LeetCode 面试经典 150 题) 82. 删除排序链表中的重复元素 II (链表)
java·c++·leetcode·链表·面试·go
嗑药狂写9W行代码31 分钟前
cesium修改源码支持4490坐标系
前端
小山不高34 分钟前
react实现leaferjs编辑器之形状裁剪功能点
前端
202636 分钟前
13.2 ssr基本原理,构建步骤
前端·vue.js
cpp加油站42 分钟前
打脸来的太快了,又发现一个Trae的宝藏功能--内置浏览器可以指定机型来显示前端界面
前端·ai编程·trae
Web极客码1 小时前
如何为WordPress启用LiteSpeed缓存
前端·缓存