compose函數
在學習redux源碼的時候看到了其中的工具函數compose,compose函數的作用就是組合函數,依次組合傳入的函數:
- 后一個函數作為前一個函數的參數
- 最后一個函數可以接受多個參數,前面的函數只能接受單個參數;后一個的返回值傳給前一個
reduce實現
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。
舉例分析:compose(f4,f3,f2,f1)(c,d,e)
- reduce回調函數第一次執行時,返回值為 函數
(...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
倒序
迭代實現
用迭代的方式實現從右到左依次執行的組合函數。
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
來記錄每次函數執行的返回值,每次都會更新,直到所有函數都執行完。才會返回最終結果
如果傳遞的函數列表為空,則返回傳入參數。
同樣的如果需要從左到右依次執行,則將funcs
倒序即可。