在学习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