纯函数的核心特征是相同输入永远返回相同输出且无副作用。它只依赖参数、不读取修改外部状态,如add=(a,b)=>a+b;避免Date.now()、++count、arr.push等破坏确定性或产生副作用的操作。

纯函数的核心特征是:相同输入永远返回相同输出,且不产生任何副作用。它像数学函数一样可预测、可复用、易测试。
输入输出确定性
纯函数的返回值只依赖于参数,不读取或修改外部变量、全局状态、DOM、文件、网络等任何外部数据。
- ✅ 正确示例:const add = (a, b) => a + b; —— 仅用参数计算,无外部依赖
- ❌ 错误示例:const now = () => Date.now(); —— 每次调用结果不同,违反确定性
- ❌ 错误示例:let count = 0; const inc = () => ++count; —— 依赖并修改外部变量
无副作用(No Side Effects)
副作用指函数执行时对函数外部世界产生的可观察影响,如修改对象属性、触发 API 请求、写入 localStorage、console.log 等。
- ✅ 安全做法:若需处理对象,应返回新对象而非修改原对象,例如用 {...obj, key: value} 或 Object.assign({}, obj, {key: value})
- ❌ 常见陷阱:arr.push(item) 修改原数组;应改用 [...arr, item]
- ⚠️ 注意:console.log 虽不影响逻辑,但属于副作用——纯函数中应避免,调试可用不影响纯度的方式(如开发环境条件打印)
如何识别与改造非纯函数
判断一个函数是否“纯”,只需问两个问题:它的输出是否只由参数决定?它是否改变或依赖函数外的任何东西?
- 把外部依赖作为参数传入:将 fetchUser(id) 改为 fetchUser(fetch, id),便于 mock 和测试
- 拆分逻辑:把“获取数据 + 渲染 DOM”拆成 parseData(raw)(纯)和 render(data)(含副作用)
- 使用不可变操作库(如 Immer)辅助管理复杂对象更新,保持语义上的纯度
纯函数的价值不止于“干净”
它支撑着函数式编程的关键能力:缓存(memoization)、并发安全、热重载友好、时间旅行调试(如 Redux DevTools)。
- 可自动缓存:若 fib(10) 已算过,下次直接返回,无需重复计算
- 可安全并行:多个纯函数调用互不干扰,适合 Web Worker 或 Promise.all
- 利于重构:只要签名不变,内部实现可任意替换,不影响调用方
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











