
JavaScript 的函数式编程(Functional Programming,简称 FP)是一种以数学函数思想组织代码的编程范式。它不强调“怎么做”(命令式步骤),而是聚焦于“做什么”——用纯函数组合、声明式表达来处理数据和逻辑。核心不是语法糖,而是思维方式的转变:避免状态变更、拒绝副作用、让数据流清晰可追溯。
不可变性是函数式编程的根基
不可变性(Immutability)指:一旦创建一个值(对象、数组等),就不再直接修改它;任何“更新”都通过生成一个新值来完成。这不是 JS 语言强制的特性,而是一种主动遵循的设计约束。
- JS 中对象和数组默认是可变的引用类型,red">直接赋值或修改属性会污染原始数据,尤其在多处共享同一对象时,极易引发难以复现的 bug
- const 只防止变量重新赋值,不阻止对象内部被修改。比如
const user = {name: "Alice"}; user.name = "Bob"是完全合法的,但破坏了不可变性 - 真正的不可变性靠约定 + 工具实现:用展开运算符、
Object.assign、map/filter/reduce等返回新结构的方法,或借助Object.freeze(浅冻结)、immer(深代理)、Immutable.js等方案
为什么不可变性如此关键
它不只是“看起来干净”,而是直接解决实际开发中的几类顽疾:
- 可预测的状态变更:每次操作都产出全新对象,旧状态完好保留。调试时你能清楚看到“上一版”和“下一版”的差异,而不是猜“谁在什么时候改了这个字段”
- 安全的并发与共享:没有共享可变状态,就不存在竞态条件(race condition)。多个函数或组件同时读取同一份数据,彼此互不影响
-
高效的变更检测:React、Redux 等依赖浅比较(
===)判断是否更新。不可变更新天然支持引用对比——只要引用变了,就说明数据变了,无需深比较,性能更优 - 纯函数的前提保障:纯函数要求“相同输入必得相同输出,且无副作用”。如果函数内部偷偷修改了传入的对象,它就不再是纯的。不可变性堵死了这条后门,让函数真正自包含、可测试、可缓存
一个简单对比:可变 vs 不可变写法
假设要给用户对象添加年龄字段:
立即学习“Java免费学习笔记(深入)”;
- ❌ 可变写法(危险):
user.age = 30;—— 原始 user 被改,所有持有该引用的地方都会感知到变化 - ✅ 不可变写法(推荐):
const newUser = {...user, age: 30};—— 原 user 不动,newUser 是独立副本,语义清晰、影响可控
不复杂但容易忽略











