纯函数是指相同输入始终返回相同输出且无副作用的函数。例如 add(a, b) 仅依赖参数并返回确定结果,不修改外部状态;而修改全局变量、改变原数组或发起网络请求等行为会导致函数“不纯”。为保持纯度,应避免外部依赖,使用扩展运算符或不可变方法处理数据,并将副作用隔离到程序边界。如 filterActiveUsers 和 getUserNames 这类函数,独立无副作用,便于测试与组合。纯函数提升代码可预测性、可测试性,支持缓存与并发优化,是函数式编程的基础。尽管实际项目难以完全消除副作用,但保持核心逻辑纯净能显著提高代码质量。

在JavaScript中,函数式编程是一种强调使用纯函数、避免状态改变和可变数据的编程范式。其中,纯函数是函数式编程的核心概念之一。理解并正确实现纯函数,有助于写出更可靠、可测试和易于维护的代码。
什么是纯函数?
一个函数被称为“纯函数”,当它满足以下两个条件:
- 相同的输入始终返回相同的输出:无论调用多少次,只要传入相同的参数,结果就一定一致。
- 没有副作用:函数执行过程中不会修改外部状态,比如不修改全局变量、不操作DOM、不发起网络请求、不修改输入参数等。
function add(a, b) {
return a + b;
}
这个函数只依赖输入参数,返回确定的结果,且不产生任何副作用,因此是纯函数。
常见的非纯函数示例
了解哪些行为会让函数变得“不纯”同样重要。
立即学习“Java免费学习笔记(深入)”;
- 依赖或修改全局变量:
let count = 0;
function increment() {
return ++count; // 依赖并修改外部状态
}
- 修改输入参数(特别是对象或数组):
function pushItem(arr, item) {
arr.push(item); // 改变了原数组
return arr;
}
这属于副作用。要保持纯,应创建新数组:
function pushItem(arr, item) {
return [...arr, item]; // 返回新数组,不修改原数组
}
如何编写纯函数?实践建议
在实际开发中,遵循以下原则可以帮助你写出更纯的函数:
- 避免使用或修改函数外部的变量,确保所有依赖都通过参数传入。
- 对对象和数组进行操作时,使用扩展运算符、
map、filter、concat等方法返回新值,而不是直接修改原数据。 - 将副作用(如日志、异步请求)隔离到程序的边界,核心逻辑保持纯净。
- 利用闭包封装状态,而非暴露在全局作用域。
function filterActiveUsers(users) {
return users.filter(user => user.isActive);
}
function getUserNames(users) {
return users.map(user => user.name);
}
// 组合使用
const activeUserNames = getUserNames(filterActiveUsers(allUsers));
每个函数都独立、无副作用,便于测试和复用。
纯函数的优势
使用纯函数带来多个好处:
- 可预测性高:输入决定输出,调试更容易。
- 易于测试:不需要模拟环境或重置状态。
- 支持缓存(memoization):相同输入可直接返回缓存结果。
- 利于并发与优化:没有共享状态,适合并行执行。
基本上就这些。掌握纯函数的写法,是迈向函数式编程的第一步。虽然在真实项目中完全避免副作用不现实,但尽量让核心逻辑保持“纯”,能显著提升代码质量。











