摘要:函數的區分是以純函數與不純函數兩者來區分,但這不光只有無副作用的差異,還有其他的條件。現在已經有一些新式的函數庫或框架例如,會特別強制要求在某些地方只能使用純函數,而具有副作用的不純函數只能在特定的情況下才能使用。
reducer(歸納函數)
reducer(歸納函數)這種函數的名稱,是由數組的一個迭代方法reduce(歸納)而來,你可以參考MDN中的相關說明:
在JS語言中的數組reduce(歸納)這個方法是一種應用于特殊情況的迭代方法,它可以藉由一個回調(callback)函數,來作前后值兩相運算,然后不斷縮減數組中的成員數量,最終返回一個值。reduce(歸納)并不會更動作為傳入的數組(調用reduce的數組),所以它也沒有副作用。一個簡單的例子如下:
const aArray = [0, 1, 2, 3, 4, 5] const sum = aArray.reduce(function(pValue, value, index, array){ return pValue + value }) console.log(sum) // 15
數組的reduce(歸納)方法,還有另一種語法樣式,是帶有初始值的,這會比較接近Redux中的reducer樣式,如下面的例子:
const initialState = 0 const sum = [1, 2, 3, 4, 5].reduce(add, initialState) function add(a, b) { // `a` 代表前一個狀態 // `b` 代表目前在數組中的項目 return a + b } console.log(sum) // 15
reduce(歸納)方法具有分散運算的特點,常見于下面幾種應用之中:
兩相比較最后取出特定的值(最大或最小值)
計算所有成員(值),總合或相乘
其它需要兩兩處理的情況(組合巢狀數組等等)
不過,Redux中的reducer與數組中的reduce方法并不相同,其中最大的差異,是reducer并不是對一整個列表進行歸納運算,而是對一個action(動作)與目前的state進行歸納運算,回傳出新的state。
副作用與純函數當一個函數是純函數時,我們可以說輸出只取決于輸入
對于函數來說,具有副作用代表著可能會更動到外部環境,或是更動到傳入的參數值。函數的區分是以 純(pure)函數 與 不純(impure)函數 兩者來區分,但這不光只有無副作用的差異,還有其他的條件。純函數(pure function)即滿足以下三個條件的函數,以下的定義是來自于Redux的概念:
給定相同的輸入(傳入值),一定會返回相同輸出值結果(返回值)
不會產生副作用
不依賴任何外部的狀態
一個典型的純函數的例子如下:
const sum = function(value1, value2) { return value1 + value2 }
套用上面說的條件定義,你可以用下面觀察來理解它是不是一個純函數:
只要每次給定相同的輸入值,就一定會得到相同的輸出值: 例如傳入1與2,就一定會得到3
不會改變原始輸入參數,或是外部的環境,所以沒有副作用
不依頼其他外部的狀態,變量或常量
那什么又是一個不純的函數?看以下的例子就是,它需要依賴外部的狀態/變量值:
let count = 1 let increaseAge = function(value) { return count += value }
在JavaScript中不純函數很常見,像我們一直用來作為輸出的console.log函數,或是你可能會在很多例子看到的alert函數,都是"不"純函數,這類函數通常沒有返回值,都是用來作某件事,像console.log會更動瀏覽器的主控臺(外部環境)的輸出,也算是一種副作用。
每次輸出值都不同的不純函數一類,最典型的就是Math.random,這是產生隨機值的內建函數,既然是隨機值當然每次運行的返回值都不一樣。
例如在數組的內建方法中,有一些是有副作用,而有一些是無副作用的,這個部份需要查對應API才能夠清楚。不會改變傳入的數組的,會在作完某件事后返回一個新數組的方法,就是無副作用的純函數(方法),而會改變原數組就算是不純函數(方法)了。
下面是兩個在數組中作同樣事情的不同方法,都是要取出只包含數組的前三個成員的數組。一個用splice,另一用是slice,看起來都很像,連這兩個方法的名稱都很像,但卻是完全屬于不同的種類:
// 不純粹(impure),splice會改變到原數組 const firstThree = function(arr) { return arr.splice(0,3) } // 純粹(pure),slice會返回新數組 const firstThree = function(arr) { return arr.slice(0,3) }
其他有許多內建的或常用的函數都是免不了有副作用的,例如這些應用:
會改變傳參(對象、數組)的函數(方法)
時間性質的函數,setTimeout等等
I/O相關
數據庫相關
AJAX
純函數當然有它的特別的優點:
代碼閱讀性提高
較為封閉與固定,可重覆使用性高
輸出輸入單純,易于測試、調試
因為輸入->輸出結果固定,可以緩存或作記憶處理,在高花費的應用中可作提高運行效率的機制
最后,并不是說有副作用的函數就不要使用,而且要很清楚的理解這個概念,然后盡可能在你自己的撰寫的一般功能函數上使用純函數,以及讓必要有副作用的函數得到良好的管控。現在已經有一些新式的函數庫或框架(例如Redux),會特別強制要求在某些地方只能使用純函數,而具有副作用的不純函數只能在特定的情況下才能使用。
注: 雖然在副作用與純函數的介紹中,我們有提到一些調用外部API(console.log/alert)、時間(Date())、隨機(Math.random)也屬于有副作用的調用,但以等級來區分它們只算是"輕度"或"微量"的副作用,這些在reducer或Action Creators能不能用?答案是可以用但也不要用,它會影響到純函數的一些優化。以在副作用的主題來說,異步運行才是"中度"或"一般"等級的副作用,我們談到副作用通常是指這個等級的。當然也有"重度"等級的副作用,那是另一個層次的特殊應用情況討論,例如組合出來的復雜異步運行流程結構。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81348.html
摘要:是分發器,是數據與邏輯處理器,會在注冊針對各個命令字的響應回調函數。當按如下方式觸發回調時,回調函數具備事件的特性。 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設計要點。本篇解釋 Shadow Widget 在 MVC、MVVM、Flux 框架之間如何做選擇。 showImg(https://segmentfault.com/img/bVOODj?w=380&h...
摘要:就是應用程序領域的狀態,它是類型中的模型的設計的概念,這設計是由架構而來的,在原本的架構中是允許多個的結構,簡化為只有單一個。的設計中是與中的相比,它們之間有一些類似的設計。 Redux里的強硬規則與設計不少,大部份都會與FP(函數式程序開發)、改進原本的Flux架構設計有關。Redux官網文檔上的三大基本原則,主要是因為有可能怕初學者不理解Redux中的一些限制或設計,所以先寫出來說...
摘要:歡迎關注源碼分析系列文章源碼分析之一源碼分析之二源碼分析之三源碼分析之四源碼分析之五文件對外暴露了一個函數,函數是的一個輔助性的函數,用于拆分里面的第一個參數函數。函數的返回值是一個函數,該函數是組合之后的一個標準的函數。 歡迎關注redux源碼分析系列文章:redux源碼分析之一:createStore.jsredux源碼分析之二:combineReducers.jsredux源碼分...
摘要:定義了幾個函數用于修改上面的幾個局部變量主要包括函數用于獲取用于替換用于修改列表用于觸發執行,生成新的,并且,執行列表中的每一個函數完整解析請參考我的,如果對您有幫助,歡迎,有任何問題也請指正。 歡迎關注redux源碼分析系列文章:redux源碼分析之一:createStore.jsredux源碼分析之二:combineReducers.jsredux源碼分析之三:bindAction...
閱讀 658·2021-11-23 09:51
閱讀 3258·2021-10-11 10:58
閱讀 15407·2021-09-29 09:47
閱讀 3529·2021-09-01 11:42
閱讀 1281·2019-08-29 16:43
閱讀 1832·2019-08-29 15:37
閱讀 2089·2019-08-29 12:56
閱讀 1718·2019-08-28 18:21