纯函数与副作用
编写可预测且便于测试的函数。
纯函数与副作用 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。
函数纯粹性的定义
纯函数具有两个特性:在输入相同的情况下始终返回相同的输出,并且不会产生可观察的副作用。纯函数具有可预测性,也易于测试。
function add(a, b) {
return a + b;
}
console.log(add(2, 3));
console.log(add(2, 3)); // always 5确定性输出
纯粹性意味着确定性。同样的参数必须始终映射到同样的结果,且不能依赖隐藏状态、时间或随机性。
function double(n) {
return n * 2;
}
console.log(double(10)); // always 20什么是副作用
副作用是函数除了返回值之外执行的任何操作,例如记录日志、修改外部状态、写入存储、进行网络调用,或改变传入的参数。
let total = 0;
function impureAdd(n) {
total += n; // side effect: mutates outer state
return total;
}
console.log(impureAdd(5));
console.log(impureAdd(5)); // 5 then 10, not pure依赖外部状态
读取可变的外部状态同样会破坏纯粹性,因为即使参数不变,输出也可能发生变化。
let rate = 1.5;
function priceImpure(x) {
return x * rate; // depends on outside variable
}
console.log(priceImpure(10)); // 15
rate = 2;
console.log(priceImpure(10)); // 20 - different result让函数变得纯粹
将函数所需的一切都作为参数传入。这样,它的结果就只取决于输入。
function price(x, rate) {
return x * rate;
}
console.log(price(10, 1.5)); // 15
console.log(price(10, 2)); // 20修改参数会使函数不纯
修改传入的对象或数组,是调用方可以观察到的副作用。纯函数不会改变它们的输入。
function impurePush(arr, x) {
arr.push(x); // mutates caller array
return arr;
}
const a = [1, 2];
impurePush(a, 3);
console.log(a); // [1, 2, 3] - caller changed返回新值
纯函数版本会构建并返回一个新值,而不是修改输入。
function pureAppend(arr, x) {
return [...arr, x];
}
const a = [1, 2];
const b = pureAppend(a, 3);
console.log(a); // [1, 2] unchanged
console.log(b); // [1, 2, 3]纯粹性的好处
纯函数非常容易测试(无需准备环境,也无需模拟对象),可以安全地缓存(记忆化),也可以安全地按任意顺序或并行运行。它们让您可以在局部范围内理解代码。
function square(n) { return n * n; }
console.log([1, 2, 3].map(square)); // [1, 4, 9]隔离非纯部分
您无法避免所有副作用;应用必须记录日志、获取数据并渲染界面。目标是将副作用推到边缘,让核心逻辑保持纯粹。
function computeTotal(items) {
return items.reduce((s, i) => s + i.price, 0);
}
const total = computeTotal([{ price: 5 }, { price: 7 }]);
console.log(total); // 12 - pure core, log at the edge引用透明性
可以将一个纯函数调用替换为它的结果,而不改变程序行为。在任何位置,add(2, 3) 都可以与 5 互换。这种性质称为引用透明性。
function add(a, b) { return a + b; }
const x = add(2, 3) + add(2, 3);
const y = 5 + 5;
console.log(x === y); // true识别非纯函数
请留意这些线索:console、Math.random、Date.now、对外部变量的赋值,或对参数的修改。任何一种情况都会使函数变为非纯函数。
function pureRoll(seed) {
return (seed * 1103515245 + 12345) % 100;
}
console.log(pureRoll(42)); // deterministic, testable快速检查
识别纯函数。
回顾
纯函数具有确定性且没有副作用:不会修改外部状态,不进行输入/输出,也不会修改参数。将依赖作为参数传入,并返回新值而不是进行修改。纯粹性带来易测试性、记忆化、引用透明性和并行安全性。请让核心逻辑保持纯粹,并将副作用推到边缘。
常见问题解答
「纯函数与副作用」课时是免费的吗?
是的 — 「纯函数与副作用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。
「纯函数与副作用」这节课中我会学到什么?
编写可预测且便于测试的函数。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 JavaScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「纯函数与副作用」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 JavaScript Academy 课中编写并运行代码吗?
能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。