本节书摘来华章计算机出版社《JavaScript应用程序设计》一书中的第2章,第2.15节,作者:Eric Elliott 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.15 无状态函数(纯函数)
纯函数往往是没有状态的。这意味着它在执行时不会对外界的变量、对象、数组等值进行修改。纯函数的输入与输出具有一对一的映射关系,无论它被使用者调用多少次。
下面是一个普通函数(非纯函数):
var rotate = function rotate(arr) {
arr.push(arr.shift());
return arr;
}
test('Rotate', function () {
var original = [1, 2, 3];
deepEqual(rotate(original), [2,3,1],
'rotate() should rotate array elements.');
// Fails! Original array gets mutated.
deepEqual(original, [1,2,3],
'Should not mutate external data.');
});
纯函数不会修改外部数据:
var safeRotate = function safeRotate(arr) {
var newArray = arr.slice(0);
newArray.push(newArray.shift());
return newArray;
}
test('safeRotate', function () {
var original = [1, 2, 3];
deepEqual(safeRotate(original), [2,3,1],
'safeRotate() should rotate array elements.');
// Passes.
deepEqual(original, [1,2,3],
'Should not mutate external data.');
});
这种特性在JavaScript应用中尤其受用,因为你经常需要同时管理多个异步事件,在这种情况下,时间成了影响代码组织的关键因素。
因为你不用再为数据共享引发的冲突而费神,无状态函数可以并发执行,这就表示可以在多个并行线程中同时进行大规模运算。换句话说,无状态函数非常适用于高并发性的应用。
在流处理任务中纯函数可以被链式调用。(例如: “枚举,处理,[处理],[处理]…收集”)
纯函数可以被进一步抽象为“无状态模块”。
注意: 为了最大限度提升代码复用性,尽可能让函数兼具“无状态”与“泛型”两种特性,像这样的函数在jQuery中有很多,它们使用起来真的很方便。