解讀之前先了准備一下基本知識
形式為...變量名,
用於獲取函數的多余參數 ,該變量將多余的參數放入數組中, 只能是參數的最后一個。
擴展運算符(spread)是三個點(...
)。它好比 rest 參數的逆運算,將一個數組轉為用逗號分隔的參數序列。
var fun1 = (...args) => console.log(...args) fun1(1,'Good') // 結果輸出 1, Good
這是一個很重要的函數 compose, 其作用紅色部分表達的很清楚。
其作用是把一系列的函數,組裝生成一個新的函數,並且從后到前,后面參數的執行結果作為其前一個的參數。
/** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for * the resulting composite function. * * @param {...Function} funcs The functions to compose. * @returns {Function} A function obtained by composing the argument functions * from right to left. For example, compose(f, g, h) is identical to doing * (...args) => f(g(h(...args))). */ export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
還是先來看一個簡單的例子,結果上確實是如我們期望的。
var fn1 = val => 'fn1-' + val var fn2 = val => 'fn2-' + val var fn3 = val => 'fn3-' + val compose(fn1,fn2,fn3)('測試') 輸出結果: fn1-fn2-fn3-測試
我們回頭看看最核心的一行代碼。
return funcs.reduce((a, b) => (...args) => a(b(...args)))
我們一步一步分解一下, func3 初始化的值為 funcs = [fn1,fn2,fn3], reduce執行
第一步時
a = fn1
b = fn2
a(b(...args)) = fn1(fn2(...args))
(...args) => a(b(...args)) = (...args) = > fn1(fn2(...args))
第二步時
a = (...ag) = > fn1(fn2(...ag)) // 避免和后面混淆,rest參數名修改為 ag
b = fn3
a(b(...args)) = a( fn3(...args) ) = fn1(fn2( fn3(...args) )) // 這一步是關鍵,b(...args)執行后作為a函數的入參,也就是 ...ag = fn3(...args)
(...args) => a(b(...args)) = (...args) = > fn1(fn2(fn3(...args)))
所以最后返回的就是這樣的一個函數 (...args) = > fn1(fn2(fn3(...args)))
再多函數,也是以此類推。
引用: