纯函数需同时满足输入完全决定输出且无副作用;如pureAdd是纯函数,impureInc因修改外部状态而非纯;slice不改原数组是纯的,splice等会修改原数组属副作用;副作用须显式隔离、集中管控并可测试。

JavaScript 函数式编程不是加个 map 或 filter 就算数,它的核心是用「纯函数」组织逻辑、把「副作用」明确隔离出来——否则只是披着函数外衣的过程式代码。
怎么一眼识别纯函数?两个硬指标必须同时满足
判断一个函数是不是纯函数,只看两件事:输入是否完全决定输出?执行过程有没有“碰”外部世界?
-
确定性:相同参数调用,返回值必须严格一致。比如
Math.pow(2, 3)永远是8,不依赖时间、随机数、全局变量或配置项 -
无副作用:不能修改传入的引用类型(如
arr.push())、不能改全局变量、不能操作document、不能发请求、不能console.log(哪怕只是调试)
function pureAdd(a, b) {
return a + b; // ✅ 纯:只靠参数,不碰外界
}
let count = 0;
function impureInc() {
return ++count; // ❌ 非纯:依赖并修改外部状态
}
为什么 splice 是“坏同学”,slice 却是“好榜样”?
数组方法是最容易踩坑的日常场景。关键看它是否「改变原数组」——这属于典型的副作用。
-
slice(start, end)返回新数组,原数组不变 → 符合纯函数精神(只要不传入 mutable 对象作为参数本身) -
splice(start, deleteCount, ...items)直接修改原数组 → 副作用立现,哪怕你没用返回值 - 同理:
sort()、reverse()、fill()全部非纯;而map()、filter()、flatMap()默认纯(前提是回调函数也纯)
const nums = [1, 2, 3]; nums.slice(0, 2); // [1, 2] → nums 还是 [1, 2, 3] nums.splice(0, 2); // [1, 2] → nums 变成 [3]!副作用已发生
副作用不是敌人,但必须“显式声明”和“集中管控”
完全没副作用的程序等于没用——你要渲染页面、要存 localStorage、要发请求。问题不在“有没有”,而在“谁负责、在哪发生、能否测试”。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“Java免费学习笔记(深入)”;
- 把副作用从计算逻辑中抽离,变成可替换的参数:比如把
Email.send(user)改成sendEmail(EmailService, user) - 在框架层统一收口:React 的
useEffect、RxJS 的subscribe、Redux-Saga 的call,都是为副作用提供可控的“出口” - 测试时直接 mock 副作用:传一个假的
fetch函数进去,断言它是否被正确调用,而不用真连网络
// ❌ 副作用藏在深处,无法测试
function signUp(name) {
const user = db.save({ name });
email.send(user); // 调用真实邮件服务
return user;
}
// ✅ 副作用外移,逻辑可测
function signUp(db, email, name) {
const user = db.save({ name });
email.send(user);
return user;
}
最容易被忽略的一点:**对象和数组作为参数传入时,函数内部对它们属性或元素的修改,就算副作用**——哪怕没动变量名本身。纯函数要求“不碰传入的引用”,只读或深拷贝后再操作。










