函數式編程是一種編程範式,常見的編程範式有如下三種:html
函數式編程的本質是將計算描述爲一種表達式求值。在函數式編程中,函數做爲一等公民,能夠在任何地方定義(在函數內或函數外),能夠做爲函數的參數和返回值,能夠對函數進行組合。git
函數式編程的準則:不依賴於外部的數據,並且也不改變外部數據的值,而是返回一個新的值給你。看個簡單的例子:web
// 非函數式的例子 let count = 0; function increment() { count++; // 依賴於函數外部的值,並改變了它的值 } // 函數式的例子 function increment(count) { return count++; }
函數式編程不依賴外部的狀態也不修改外部的狀態,函數調用的結果不依賴調用的時間和位置,這些寫代碼容易進行推理,不易犯錯,並且單測和調試都更簡單。即函數編程採用純函數。shell
純函數是這樣一種函數,即相同的輸入,永遠會獲得相同的輸出,並且沒有任何可觀察的反作用。
反作用可能包含,但不限於:數據庫
反作用是在計算結果的過程當中,系統狀態的一種變化,或者與外部世界進行的可觀察的交互。
純函數的好處:編程
純函數能根據輸入來作緩存(memoize技術)設計模式
const memoize = function(f) { const cache = {}; return function() { const argStr = JSON.stringify(arguments); if (!cache[argStr]) { cache[argStr] = f.apply(f, arguments); } return cache[argStr]; } }
可移植性/自文檔化
純函數的輸出只依賴與它的輸入,依賴很明確,易於理解。因爲純函數不依賴它的上下文環境,所以咱們能夠輕易的把它移植到任何地方運行它。瀏覽器
可測試性
咱們沒必要在每次測試前都去配置和構造初始環境,只需簡單給函數一個輸入,而後斷言它的輸出就行了。緩存
合理性
因爲純函數老是可以根據相同的輸入返回相同的輸出,因此它們就可以保證老是返回同一個結果,這也就保證了引用透明性。併發
並行執行
咱們能夠並行運行任意純函數。由於純函數根本不須要訪問共享的內存,並且根據其定義,純函數也不會因反作用而進入競爭態。
並行代碼在服務端 js 環境以及使用了 web worker 的瀏覽器那裏是很是容易實現的,由於它們使用了線程(thread)。不過出於對非純函數複雜度的考慮,當前主流觀點仍是避免使用這種並行。
這裏咱們先不展開這些技術的細節內容,本文咱們先側重於對函數式編程有一個總體上的認識,具體的技術細節咱們將在下一章展開。
咱們先來看如下幾種觀點:
我想說的是這種偏激的觀點是不正確的,咱們不該該把函數式編程和命令式編程對立起來,咱們更多的時候須要考慮的是技術的適用場景。函數式編程寫起代碼來,有必定的難度,若是一個團隊的總體水平達不到,那麼寫代碼的質量和效率還不如採用命令式編程好。函數式編程利用純函數的無狀態性,它的好處很是多(結果可預期、利於測試、利於複用、利於併發),但一個系統工程的代碼,是不可能所有采用純函數來寫的。當咱們越貼近業務,咱們就離純函數與無狀態越遠。
函數式編程很是重要,學習它咱們能打開咱們的思惟方式,使用它也有不少好處,但它也有一些侷限,咱們應該客觀看待。保持開放的心態,根據實際場景選擇合適的技術,是一個工程師基本的素養。
https://llh911001.gitbooks.io...
http://www.ruanyifeng.com/blo...
https://coolshell.cn/articles...
https://www.zhihu.com/questio...
https://zhuanlan.zhihu.com/p/...