在學習redux源碼的時候看到了其中的工具函數compose,compose函數的做用就是組合函數,依次組合傳入的函數:redux
redux中是使用reduce
實現的數組
function compose(...funcs) { //沒有傳入函數參數,就返回一個默認函數(直接返回參數) if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { // 單元素數組時調用reduce,會直接返回該元素,不會執行callback;因此這裏手動執行 return funcs[0] } // 依次拼湊執行函數 return funcs.reduce((a, b) => (...args) => a(b(...args))) }
reduce的詳細說明能夠查閱MDN。app
舉例分析:compose(f4,f3,f2,f1)(c,d,e)
函數
(...args) => f4(f3(...args))
,做爲下一次執行的a參數(...args) => f4(f3(f2(...args)))
,做爲下一次執行的a參數(...args) => f4(f3(f2(f1(...args))))
最右邊的參數f1
能夠接受多個參數,而後返回結果傳給下一個函數f2
,返回結果再傳入f3
··· f3
最早被調用,會等待f2
的結果,再等待f1
的結果。工具
let a = (x,y) => x + y, b = x => x * x, c = x => x === 0 ? x : 1/x; compose(c,b,a)(1,2); // 1/9
那麼若是想從左到右返回結果呢?學習
reduceRight
funcs
倒序用迭代的方式實現從右到左依次執行的組合函數。this
function compose(...funcs) { let length = funcs.length; return function(...arg) { let index = length - 1, result = length > 0 ? funcs[index].apply(this,arg) : arg; //注意arg爲數組,要用apply while(--index >=0 ) { result = funcs[index].call(this,result); } return result; } }
經過index
來標記應該執行哪一個函數,這裏是從最右邊(length - 1
)開始執行的,每執行一個index
就減1,直到index
爲0
(最左邊)爲止。
用result
來記錄每次函數執行的返回值,每次都會更新,直到全部函數都執行完。纔會返回最終結果
若是傳遞的函數列表爲空,則返回傳入參數。code
一樣的若是須要從左到右依次執行,則將funcs
倒序便可。ip