純函數的定義通俗點說就是:固定的輸入,得到固定的輸出,不受到來自外部的任何干擾
純函數不會隨着執行次數的增加而改變輸出的值,比如數組中的splice和slice,其中splice不是純函數,而slice則爲定義的純函數,示例如下:
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);
//=> []
splice隨着執行次數的增多,返回的值就出現了差異,這與純函數的思想相背離。。。
至於不受到外部干擾的解釋是,有的函數會在內部與外部的全局變量產生關聯,是的函數的輸出會根據外部值得變化發生改變,具體的例子如下:
// 不純的
var minimum = 21;
var checkAge = function(age) {
return age >= minimum;
};
// 純的
var checkAge = function(age) {
var minimum = 21;
return age >= minimum;
};
示例中不是存函數主要原因是函數內部會受到外部變量minmum的影響
追求純函數的理由
- 可緩存性
純函數可以根據輸入來緩存結果,可以加快程序重複執行時的運算速度,具體如何實現緩存,可以單獨去了解下
var squareNumber = memoize(function(x){ return x*x; });
squareNumber(4);
//=> 16
squareNumber(4); // 從緩存中讀取輸入值爲 4 的結果
//=> 16
可緩存性還有個好處就是可以將非純函數,緩存爲純函數,即延遲執行
- 可移植性
在js中可移植性意味着可以將函數序列化並通過socket發送。純函數與環境無關,可以在任何地方運行
- 可測試性
因爲其其固定的輸入與輸出,使得測試會更加的簡便
- 並行代碼
因爲純函數不需要訪問共享內存,所以函數間也不會因爲引用而進入競爭狀態