Function Programming - 纯函数(Pure Function)
纯函数的定义,非常重要!!
Pure function 意指相同的输入,永远会得到相同的输出,而且没有任何显著的副作用。
老样子,我们还是从最简单的栗子开始:
var minimum = 21; var OutercompareNumber = function(number) { return number > minimum; } 以及 var InnercompareNumber = function(number) { var minimum = 21; return number > minimum; }
以上两个函数的区别大家都看到了,一个minimum定义在函数外面,一个在函数里面;那么我们调用这两个函数的结果就很有可能是不一样的;比如,我们在调用OutercompareNumber的时候,假设number这个参数我们始终传20,minimum不改变的情况下,结果为false;但一旦minimum改变成19,结果就为true,OutercompareNumber就不是pure的函数;而InnercompareNumber这个函数,如果始终传20,结果始终为false,那么我们就说InnercompareNumber为纯函数(pure function)。
总结来说,就是传的参数相同的情况下,永远会得到相同的输出。
那么我们说的显著的副作用又是什么呢?我们来看下定义:副作用是在计算结果的过程中,系统状态的一种改变,或是外部世界可观察的交互作用。
比如,更改档案系统,发送http请求等,只要与function外部环境发生交互作用的都是副作用。
那么,如何避免这些副作用呢,继续来看栗子:
var callRequest = function(url, params) { return $.getJSON(url, params); } 与 var delayCallRequest = function(url, params) { return function() { return $.getJSON(url, params); } }
callRequest直接返回了一个http请求,那么这个是与外界交互,返回的结果有太大的不确定性,所以是impure的函数;而delayCallRequest采用了延迟执行的方式,返回了一个函数,只有调用这个函数的时候才会发送请求:delayCallRequest(url, params)(),但就delayCallRequest而言,传相同的参数,得到的结果是一样的,是相同参数的函数,所以这个是一个pure的函数。
再看一个栗子,我们深入理解一下:
//impure var signUp = function(attrs) { var user = saveUser(attrs); welcomeUser(user); }; var saveUser = function(attrs) { var user = Db.save(attrs); ... }; var welcomeUser = function(user) { Email(user, ...); ... }; //pure var signUp = function(Db, Email, attrs) { return function() { var user = saveUser(Db, attrs); welcomeUser(Email, user); }; }; var saveUser = function(Db, attrs) { ... }; var welcomeUser = function(Email, user) { ... };
pure函数会自给自足,函数的依赖会特别明确,像impure的函数,Email做了什么我们并不知道,Db在背后做了什么,我们也无所得知,所以他们以参数的形式,保证输入相同的情况下,得到的结果一定是相同的,注意,这里也用了延迟执行的方式。
好啦,今天的纯函数就介绍到这里,我们下回再见~~早安!