纯函数是不依赖也不修改外部状态、输入相同则输出恒定且无副作用的函数;其核心特征为确定性(仅依赖参数)和无副作用(不改变外部环境),因而更易测试、可预测、可并行执行。

纯函数是指既不依赖外部状态、也不修改外部状态的函数。它只根据输入参数返回确定结果,相同输入永远得到相同输出,且没有副作用。
纯函数的两个核心特征
1. 确定性(无外部依赖):函数内部不读取或使用任何外部变量(如全局变量、模块变量、时间、随机数等),所有数据都来自参数。
2. 无副作用(不改变外部环境):不修改传入的对象或数组,不调用 console.log、setTimeout、fetch 等外部 API,不修改 DOM,不更改全局状态。
✅ 正确示例:
立即学习“Java免费学习笔记(深入)”;
const add = (a, b) => a + b;
const getFullName = (user) => `${user.firstName} ${user.lastName}`;
❌ 非纯函数示例:
let counter = 0; const increment = () => ++counter; // 依赖并修改外部变量const now = () => new Date(); // 每次调用结果不同
const logAndDouble = (x) => { console.log(x); // 副作用 return x * 2; };
为什么纯函数更容易测试
测试的核心目标是验证“给定输入 → 是否得到预期输出”。纯函数天然契合这一目标,因为它的行为完全可预测、可隔离。
- 无需模拟(mock)外部依赖:不用 mock 时间、API、数据库或全局状态,直接传参断言结果即可
- 测试用例简洁稳定:同一个输入反复运行,结果永不变化,不会因执行顺序、环境时间或共享状态而失败
- 便于单元测试和快照测试:比如对一个格式化函数,输入 "2023-01-01" 总是返回 "Jan 1, 2023",可放心写断言
- 支持并行/重复执行:多个测试可以同时跑,或单个测试反复运行,不影响彼此
实际开发中怎么写出纯函数
不是所有函数都能或都需要写成纯函数,但关键逻辑(如数据转换、计算、校验)尽量保持纯净,能显著提升可维护性。
- 避免直接修改参数对象:用展开运算符或 Object.assign 创建新对象,而不是 user.name = 'Alice'
- 把副作用抽离到外层:比如把 API 调用放在事件处理函数里,让数据处理逻辑本身保持纯函数
- 用函数式工具辅助:如 map/filter/reduce、immer(用于安全地“看起来”修改不可变数据)
- 注意引用类型陷阱:{...obj} 只是浅拷贝,嵌套对象仍可能被意外修改,必要时用深克隆或结构化处理
纯函数不是银弹,但值得优先考虑
它不能替代异步、状态管理或 UI 渲染,但在业务逻辑层、工具函数、reducer、selector 等场景中,坚持纯函数原则会让代码更可靠、更易理解和协作。测试不再是“碰运气”,而是真正成为质量的守门人。










