compose
模塊的代碼十分簡練,可是實現的做用倒是十分強大。redux
爲什麼稱爲redux?有人說就是reduce
和flux
的結合體,而reduce
正是compose
模塊的核心。git
compose
模塊所實現的功能強大而簡單:從右到左,組合參數(函數)。因此,傳遞給compose
方法的參數,必須都是函數類型的(這一點,在源碼中沒有判斷,多是由於這個模塊是redux內部使用的模塊,沒有對外暴露,因此不須要很強的校驗。)。例如:github
compose(f, g, h) ====> (...args) => f(g(h(...args)))
模塊的代碼很簡單,可是涉及到的內容卻很重要,下面一點一點的看。redux
reduce是什麼?數組
reduce
是es5
中的數組的一個方法,對累加器和數組中的每一個元素(從左到右)應用一個函數,將其減小爲單個值。函數簽名爲:函數
arr.reduce(callback[, initialValue])
callback是執行數組中每一個元素的函數,這個函數接收幾個參數:測試
綜上,reduce方法詳細的簽名就是:es5
arr.reduce(function (accumulator, currentValue, currentIndex, array) {}[, initialValue])
幾個小Demospa
[1,2,3,4,5].reduce((a, b) => a + b) // 15
[[0, 1], [2, 3], [4, 5]].reduce((a, b) => { return a.concat(b); }, []); // [ 0, 1, 2, 3, 4, 5 ]
關於reduce詳細的文檔能夠參考Array.prototype.reduceprototype
明白了reduce
是怎麼回事以後,咱們先來看一下compose
有什麼神奇的效果:code
import compose from '../src/compose' // function f const f = (arg) => `函數f(${arg})` // function g const g = (arg) => `函數g(${arg})` // function h 最後一個函數能夠接受多個參數 const h = (...arg) => `函數h(${arg.join('_')})` const r = compose(f, g, h) console.log(typeof r) // function console.log(r(1,2,3)) //函數f(函數g(函數h(1_2_3)))
從上面能夠的代碼能夠看出:compose的運行結果是一個函數,調用這個函數所傳遞的參數將會做爲compose最後一個參數的參數,從而像'洋蔥圈'似的,由內向外,逐步調用。
源碼
export default function compose(...funcs) { // funcs是一個保存着全部參數函數的數組 // 若是沒有傳遞任何參數,就返回一個函數,這個函數是輸入什麼獲得什麼。 if (funcs.length === 0) { return arg => arg } // 只傳遞一個參數的時候,就直接把這個函數返回 if (funcs.length === 1) { return funcs[0] } // 返回組合函數 return funcs.reduce((a, b) => (...args) => a(b(...args))) }
這就是對compose
源碼的一個總體解讀,水平有限,歡迎拍磚。後續的源碼解讀和測試例子能夠關注:redux源碼解讀倉庫