纯函数与副作用
什么条件同时成立时函数才是纯的?
- 确定性: 相同输入总得到相同输出;
- 封闭性: 结果不依赖函数外部的可变状态;
- 无副作用: 计算不会修改函数外部状态;
const greet = (name) => `Hi, ${name}`;
greet("Brianne"); // 始终为 'Hi, Brianne'
哪些写法破坏纯度?
window.name = "Brianne";
const readGlobal = () => `Hi, ${window.name}`; // 读取外部可变状态
let greeting;
const writeGlobal = (name) => {
greeting = `Hi, ${name}`; // 修改外部状态
};
- 隐式输入: 时间、随机数、配置、数据库和全局变量;
- 隐式输出: 写文件、修改变量、DOM 更新和日志;
什么是副作用?
- 副作用: 表达式除返回值外,还读取或写入外部可变状态;
new Date(): 读取随时间变化的外部世界;console.log(): 向外部输出并改变可观察环境;
const differentEveryTime = new Date();
console.log("IO is a side effect!");
幂等与纯函数是一回事吗?
- 幂等: 把函数再次用于自己的结果,不会继续改变结果;
- 形式:
f(f(x)) = f(x); - 区别: 纯度关心输入、输出和副作用;幂等关心重复应用后的稳定性;
Math.abs(Math.abs(10)) === Math.abs(10);
sort(sort([2, 1])); // 与 sort([2, 1]) 相同