你是否经常处理对象和数组的嵌套数据?写了一堆嵌套循环、变量名重复、逻辑难懂?在 JavaScript 中,有两个方法看起来简单,组合起来却能解决 80% 的对象结构转换问题,它们就是:
Object.entries
+Array.prototype.reduce
无论你是想从后台 API 拿到数据后整理格式,还是要渲染复杂的表格,只要处理的是“对象 + 数组”的嵌套结构,这两个方法就是你最好的朋友。
🧩 Object.entries:让对象也能玩数组操作
你平时用 for...in
遍历对象:
const user = { name: 'Alice', age: 30 };
for (let key in user) {
console.log(key, user[key]);
}
其实用 Object.entries
你可以写得更简洁:
Object.entries(user).forEach(([key, value]) => {
console.log(key, value);
});
✅ 它做了什么?
把对象变成了“键值对数组”:
const obj = { a: 1, b: 2 };
console.log(Object.entries(obj));
// 输出: [['a', 1], ['b', 2]]
这样你就可以用数组的方式处理对象了,比如 map
、reduce
、filter
都可以用上!
reduce:最通用的结构转换工具之一
reduce
是数组中最强大的方法之一,它的作用是:
把一个数组 “归纳”为一个结果(可以是数字、对象、数组、任何你想要的结构)
🎯 最常见的例子:数组求和
const arr = [1, 2, 3];
const sum = arr.reduce((acc, cur) => acc + cur, 0);
// acc 是累加器,cur 是当前项
console.log(sum); // 6
🧠 reduce 的参数结构
array.reduce((accumulator, currentValue, index, array) => {
// 每一步的处理逻辑
return newAccumulator;
}, initialValue);
accumulator
:累加器(结果容器)currentValue
:当前项initialValue
:初始值(比如 0 或 {})
📦 组合起来,用 entries + reduce 解决问题
📚 场景:图书分类数据转扁平列表
你有这样一个对象:
const booksByCategory = {
fiction: [
{ title: '1984' },
{ title: 'Brave New World' }
],
tech: [
{ title: 'Clean Code' },
{ title: 'You Don’t Know JS' }
]
};
你希望把它转换成一个数组,每本书都带上它属于哪个分类:
[
{ title: '1984', category: 'fiction' },
{ title: 'Brave New World', category: 'fiction' },
{ title: 'Clean Code', category: 'tech' },
{ title: 'You Don’t Know JS', category: 'tech' }
]
🛠 用 entries + reduce 来写:
const result = Object.entries(booksByCategory).reduce((acc, [category, books]) => {
const newBooks = books.map(book => ({
...book,
category
}));
return acc.concat(newBooks);
}, []);
📌 解析:
Object.entries
把对象变成:[['fiction', [...]], ['tech', [...]]]
- 每一类
books
用map
加上分类名 reduce
把所有类的书合并到一个数组里
🎨 图示结构(可选配图)
输入对象:
{
fiction: [A, B],
tech: [C, D]
}
转换过程:
Object.entries → [['fiction', [A, B]], ['tech', [C, D]]]
每组 map 添加 category
reduce 合并所有数组
输出结果:
[{...A, fiction}, {...B, fiction}, {...C, tech}, {...D, tech}]
🧠 你已经在用函数式编程了
虽然我们没写什么“函数式编程”的术语,但你其实已经在用了:
概念 | 表现在哪 |
---|---|
声明式编程 | 一步表达“我要什么结构” |
不可变数据 | 没有修改原数据,而是生成新数组 |
纯函数 | map 和 reduce 都是无副作用的转换 |
可组合 | 每一步操作都可以替换或重用 |
函数式编程不是玄学,它可以是你写 JS 的“第二语言”。
Object.entries + reduce
是进入函数式编程思维的绝佳切入点:
- 🧠 不改原数据
- 🎯 聚焦目标结构
- 💪 代码更可读、可维护、可测试
✅ 什么时候该用它?
只要你遇到这类问题:
- 需要把对象转数组(或反过来)
- 想要遍历对象内部的数据并做处理
- 想要结构清晰、逻辑集中
就大胆用 Object.entries + reduce
吧!
📘 什么是函数式编程(Functional Programming)?
函数式编程(Functional Programming, 简称 FP)并不是让你写成数学公式,而是一种更偏“声明式”的写法风格,强调:
- 纯函数:不修改外部变量,每次调用结果相同
- 不可变数据:不改变原始输入,而是生成新值
- 函数组合:将多个小函数组合成复杂逻辑
- 声明式写法:描述“做什么”,而不是“怎么做”
🔁 函数式 vs 命令式:写法上的哲学分歧
你可以这样理解这两者的对比:
项目 | 函数式编程 | 命令式编程 |
---|---|---|
编程风格 | 声明式:“做什么” | 命令式:“怎么做” |
示例操作 | map , reduce , filter | for , if , let ... |
数据处理 | 返回新值(不可变) | 直接修改变量(可变) |
函数特性 | 纯函数,组合函数 | 过程函数,带副作用 |
举例 | [].map(fn) | for (let i = 0; i < arr.length; i++) {} |
🧱 别的编程范式了解下
除了函数式和命令式,常见的还有:
编程范式 | 简介 |
---|---|
面向对象编程(OOP) | 以对象为核心,封装状态与行为(如 Java、C++、TS) |
事件驱动编程(EDP) | 常见于前端 UI 和 Node.js(如监听事件、回调) |
响应式编程(Reactive) | 数据变化自动驱动 UI(Vue、React 就是响应式思想) |
声明式编程(Declarative) | 只告诉系统“要什么”,不写具体步骤(SQL、HTML、React 组件) |
🧠 最后总结
Object.entries + reduce
是 JS 数据处理的黄金组合。
学会它,你可以少写很多嵌套循环,多写一些优雅、好维护的结构转换代码。
希望你读完后,能在下一次处理数据结构时,自然地想到:
Object.entries + reduce
这不是技巧,是一种写代码的思维方式。
👇 如果你觉得这篇文章有启发,欢迎点赞、收藏,或者评论区聊聊你的理解,一起把代码写得更优雅、更聪明。