compose 函數就是將幾個有特點的函數拼湊在一起, 讓它們結合, 產生一個嶄新的函數。
作用:可以把一個函數的運行結果當作實參傳給下一個函數,即實現層級嵌套的函數調用扁平化。
比如有這樣的需求,要輸入一個名字,這個名字由 firstName
, lastName
組合而成,然后把這個名字全部變成大寫輸出來,比如輸入 sea
,xiao,
我們就要打印出來,‘HELLO, SEA XIAO’
。我們考慮用函數組合的方法來解決這個問題,需要兩個函數 greeting
, toUpper
var greeting = (firstName, lastName) => 'hello, ' + firstName + ' ' + lastName; var toUpper = str => str.toUpperCase(); var fn = compose(toUpper, greeting); console.log(fn('sea', 'xiao'));
這個簡單版的 compose 就可以解決
const compose = (fn2,fn1) => (firstName,lastName)=> fn2(fn1(firstName,lastName))
如果還想再加一個處理函數,不需要修改 fn
,只需要在執行一個 compose
,比如我們再想加一個 toLower,只需要這樣做
var toLower = str => str.toLowerCase(); var newFn = compose(trim, fn) console.log(newFn('sea', 'xiao'))
但是如果我們想一次性傳入兩個及以上的參數,這個簡版的 compose 就不能滿足要求,以下就是修改版的 compose:
function compose(...funcs) {
// 傳遞的函數集合
return function (...args) {
let length = funcs.length;
if (length == 0) {
//=>一個函數都不需要執行,直接返回ARGS
return args;
}
if (length == 1) {
//=>只需要執行一個函數,把函數執行,把其結果返回即可
return funcs[0](...args)
}
return funcs.reduce((x,y)=> typeof x === "function" ? x(y(...args)) : y(...args))
}
}
reduce 遞歸在 compose 中相當重要