`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 能让你写出 少但更强的代码

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

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

相关推荐
optimistic_chen几秒前
【Vue3入门】Pinia 状态管理 和 ElementPlus组件库
前端·javascript·vue.js·elementui·pinia·组件
kgduu1 分钟前
js之网络请求与远程资源
开发语言·javascript·网络
酉鬼女又兒3 分钟前
零基础入门前端JavaScript 核心语法:var/let/const、箭头函数与 setTimeout 循环陷阱全解析(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·蓝桥杯
Bling_Bling_17 分钟前
【无标题】
前端·网络协议
We་ct8 分钟前
React Diff & Key 核心解析
开发语言·前端·javascript·react.js·前端框架·reactjs·diff
哥本哈士奇9 分钟前
Vue 3 快速入门:从零搭建前后端 CRUD 应用
前端·javascript·vue.js
biubiubiu07069 分钟前
Agent 是如何拥有“手脚”的(ReAct 运行流程)
开发语言·前端·javascript
摸鱼的春哥13 分钟前
Agent教程21:知识图谱🕸,让AI🤖学会联想
前端·javascript·后端
SuperEugene13 分钟前
Vue3 组件拆分实战规范:页面 / 业务 / 基础组件边界清晰化,高内聚低耦合落地指南|Vue 组件与模板规范篇
前端·javascript·vue.js·前端框架
泯泷13 分钟前
阶段二:为什么先设计指令集,编译器和运行时才能稳定对齐?
前端·javascript·架构