纯函数必须满足:不读取外部可变状态、不修改输入或外部对象、所有依赖显式传参、无任何可观察副作用;仅依据参数进行计算并返回新数据。

要保证 JavaScript 中的纯函数在相同输入下总得到相同输出,关键在于切断所有可能引入“不确定性”的外部依赖和隐式状态。
不读取任何外部可变状态
函数体内不能访问或依赖全局变量、模块级变量、闭包中被修改的变量,也不能调用 Date.now()、Math.random()、location.href 这类每次调用结果都不同的值。哪怕只读一次当前时间,就打破了确定性。
- ❌ 错误示例:
const now = Date.now(); return input + now; - ✅ 正确做法:把时间作为参数显式传入,如
addTimestamp(input, timestamp)
不修改任何输入参数或外部对象
纯函数必须保持“不可变性”——不对传入的对象、数组做原地修改(如 push、splice、sort),也不改变闭包外的变量。所有变更都应通过返回新数据完成。
- ❌ 错误示例:
arr.push(item); return arr;(改变了原数组) - ✅ 正确做法:
return [...arr, item];或arr.concat(item)
所有依赖都必须显式传参
函数行为只能由参数决定,不能靠环境、配置、上下文“悄悄影响”。比如格式化日期,不能内置时区逻辑,而应把 timezone 或 locale 作为参数暴露出来。
- ❌ 隐式依赖:
formatDate(date) { return new Intl.DateTimeFormat('zh-CN').format(date); } - ✅ 显式控制:
formatDate(date, { locale = 'zh-CN', timeZone = 'Asia/Shanghai' })
避免语义上可观察的副作用
所谓“可观察的副作用”,是指函数执行后,外界能检测到除返回值以外的变化,比如:修改 DOM、发起请求、写 localStorage、触发 console.log、抛出未捕获错误等。这些行为必须彻底剥离出纯函数体。
- 纯函数只做计算:接收数据 → 处理 → 返回新数据
- 副作用交给专门的函数处理,例如
fetchUser(id)负责请求,transformUser(data)负责解析——后者才是纯的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











