

新闻资讯
行业动态纯函数需同时满足输入完全决定输出且无副作用;如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; // ❌ 非纯:依赖并修改外部状态
}
数组方法是最容易踩坑的日常场景。关键看它是否「改变原数组」——这属于典型的副作用。
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、要发请求。问题不在“有没有”,而在“谁负责、在哪发生、能否测试”。
立即学习“Java免费学习笔记(深入)”;
Email.send(user) 改成 sendEmail(EmailService, user)
useEffect、RxJS 的 subscribe、Redux-Saga 的 call,都是为副作用提供可控的“出口”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;
}
最容易被忽略的一点:**对象和数组作为参数传入时,函数内部对它们属性或元素的修改,就算副作用**——哪怕
没动变量名本身。纯函数要求“不碰传入的引用”,只读或深拷贝后再操作。