javascript是一門多範式(multi-paradigm)的編程語言,它即支持命令式(imperative)/面向過程(procedural)編程,也支持面向對象編程(oop object-Oriented Programming),還支持函數式編程(functional programming).
常見的三種編程範式javascript
1 命令式 c
2 函數式 lisp
3 面向對象 java c++java
咱們先來看下命令式是怎麼求一個數組的最大值的
var arr = [1,2,3,4,5,6];
var len = arr.length;
var max = arr[0];
for(var i=0;i<len;i++){
if(arr[i] > max){c++
max = arr[i];
}
}
這就是命令式編程 for循環的形式 7行代碼,多了幾個全局變量編程
咱們嘗試改造下,採用排序的方式數組
var max = arr.sort((a, b) => b - a)[0]; 緩存
確實簡潔很多。但有一個負做用,把arr的內容給修改了。這不是一個純函數該乾的事。咱們再優化下數據結構
var sum = arr.reduce(function (a, b) {
return a > b?a:b
});
再變成箭頭函數
var sum = arr.reduce((a,b) =>{return a>b?a:b;});
沒有多餘的全局變量,也沒有修改調動的數組。這就是一個函數式編程的一個典型例子。app
近年來。函數式編程愈來愈多獲得開發這的青睞,函數式編程是一種強調減小對程序外部狀態產生改變的方式。所以它鼓勵使用不可變數據結構合純函數編程,鼓勵使用聲明式編程而非命令式編程,經過簡而已懂的函數命令方式,描述目標性質,獲得想要的結果,而非流程式,指令式。函數式編程即不依賴外部狀態,也不修改外部狀態,能夠使代碼更容易理解,維護,測試,不易出錯。編程語言
函數式編程有5大特性函數式編程
純函數是一種函數,它不改變程序的外部狀態,也不會形成數據可變性,純函數的輸出徹底依賴於它的輸入值,對於相同的輸入,永遠返回相同的輸出。
好比 slice 和 splice,這兩個函數的做用並沒有二致——可是注意,它們各自的方式卻大不一樣,但無論怎麼說做用仍是同樣的。咱們說 slice 符合純函數的定義是由於對相同的輸入它保證能返回相同的輸出。而 splice 卻會嚼爛調用它的那個數組,而後再吐出來;這就會產生可觀察到的反作用,即這個數組永久地改變了。
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); //=> []
純函數的好處很是的多。這讓單元測試,可緩存性,可移植行,文檔化,成爲很輕鬆的事。
不可變數據指一個值,一旦被建立,就永遠不會發生改變。在js基本數據類型中,數字,字符串和布爾值是永遠不變的。但對象和數組的數據結構在某些操做下是可變的。
var x = [1,2] console.log(x) x.push(3); console.log(x) //數組可變,x被改變了 var x = [1,2],y; console.log(x); y = x.concat([3]); console.log(x) //數組不可變
函數反作用是指當調用函數是,除了返回函數值以外,還對該函數外部的狀態產生了改變。函數反作用會給程序帶來沒必要要的麻煩,給程序帶來潛在的錯誤,而且下降程序的可讀性。
var x = 1 var fn = function(y){ x = x+y } fn(2) console.log(x)
函數組合就是組合兩到多個函數來生成一個新函數的過程。將函數組合在一塊兒,就像將一連串管道扣合在一塊兒,讓數據流過同樣。
簡而言之,函數 f 和 g 的組合能夠被定義爲 f(g(x)),從內到外(從右到左)求值。也就是說,求值順序是:
例如underscore裏面compose函數的實現
function compose() { var args = arguments; var start = args.length - 1; return function() { var i = start; var result = args[start].apply(this, arguments); while (i--) result = args[i].call(this, result); return result; }; };
compose(d, c, b, a)
函數柯里化指把接受多個參數的多參函數轉換成每次只接受一個參數的單參函數,而且返回能夠接受餘下參數的新函數,最大的特色是延遲執行,增長了函數的適用性。
上述幾個點均可以分開單獨的來闡述,網上也有特別多的介紹。後續再一一展開來描述下上面的特性
正在努力的改變本身的編碼習慣朝着函數式編程努力着