什么是纯函数?
纯函数是这样一种函数,即相同的输出,永远会得到相同的输出,而且没有任何可观察的副作用。‘副作用’是在计算结果的过程中,系统状态的一种变化,或者与外部世界进行可观察的交互。概括来讲,只要跟函数外部环境发生的交互就都是副作用。函数式编程的哲学就是假定副作用是造成不正当行为的主要原因。并不是说,要禁止使用一切副作用,而是,要让他们在可控的范围内发生。从定义上来说,纯函数必须能根据相同的输入返回相同的输出;如果函数需要跟外部事物打交道,那么就无法保证这一点了。
var xs = [1,2,3,4,5]; // 纯函数 xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] // 非纯函数 xs.splice(0,3); //=> [1,2,3] xs.splice(0,3); //=> [4,5] xs.splice(0,3); //=> []
// 不纯的 var minimum = 21; var checkAge = function(age) { return age >= minimum; }; // 纯函数 var checkAge = function(age) { var minimum = 21; return age >= minimum; };
在不纯的版本中,函数的结果取决于 minimum 这个可变变量的值。换句话说,它取决于系统状态。输入值(参数)之外的因素能够左右函数的返回值,会使函数变得不纯,导致我们思考整个软件是总是要面对函数外部复杂多变的系统状态。
如果一个函数是纯函数,它的输入就直接表明了输出,那么就没有必要实现具体的细节了,因为函数仅仅只是输入到输出的映射。基于这个概念,就可以逐步构建出函数式编程的蓝图。
传统的命令式编程方法和过程都深深地植根于它们所在的环境中,通过状态、依赖和有效作用达成。而纯函数则与环境无关,可以在任何地方运行它,并保证相同的输入总会有相同的结果。
#纯函数的好处
1.引用透明性
所谓的引用透明性就是一段代码可以替换成它执行所得的结果,而且是在不改变整个程序行为的前提下,替换的。而纯函数就是引用透明的。引用透明意味着可以进行等式推导(就像高中数学的推导),等式推导可以为重构和理解代码带来相当大的分析能力。
//太傻 var getServerStuff = function(callback) { return ajaxCall(function(json) { return callback(json); }); }; //这才像样 var getServerStuff = ajaxCall; //因为 return ajaxCall(function(json) { return callback(json); }); //等价于 return ajaxCall(callback(json)); //而 var getServerStuff = function(callback) { return ajaxCall(callback(json)); }; //就等于... var getServerStuff = ajaxCall;
2.并行代码
纯函数不依赖于系统状态的特点,我们就可以并行运行任意纯函数。因为纯函数根本不需要访问共享的内存,而且根据其定义,纯函数也不会因副作用而进入竞争态。
时间: 2024-10-20 09:09:24