compose源码分析compose模块的代码非常简洁,但是实现起来非常强大。redux为什么叫redux?有人说是reduce和flux的结合,reduce是compose模块的核心。compose模块实现的功能强大而简单:从右到左,组合参数(函数)。所以传给compose方法的参数必须全部是function类型(这一点在源码中没有判断,可能是因为这个模块是redux内部使用的,没有对外暴露,所以没有强验证是必须的。)。例如:compose(f,g,h)====>(...args)=>f(g(h(...args)))模块的代码很简单,但是涉及到的内容很重要,下面一点一点看。什么是减少?reduce是es5中数组的一种方法,它将一个函数应用于累加器和数组中的每个元素(从左到右),将其减少为单个值。函数签名是:arr.reduce(callback[,initialValue])回调是一个函数,它执行数组中的每个元素。该函数接收几个参数:accumulator:上一次回调调用的返回值。如果是第一次调用,那么这个值为initialValue。如果未提供initialValue,则使用数组的第一个元素。currentValue:数组正在处理的元素currentIndex:数组正在处理的元素的当前索引array:调用reduce方法的数组综上所述,reduce方法的详细签名为:arr.reduce(function(accumulator,currentValue,currentIndex,array){}[,initialValue])几个小Demo数组的总和[1,2,3,4,5].reduce((a,b)=>a+b)//15个数组是扁平化[[0,1],[2,3],[4,5]]。reduce((a,b)=>{returna.concat(b);},[]);//[0,1,2,3,4,5]关于reduce的详细文档,请参考Array.prototype.reduce了解了reduce是怎么回事之后,我们来看看compose的神奇效果:importcomposefrom'../src/compose'//functionfconstf=(arg)=>`functionf(${arg})`//functiongconstg=(arg)=>`functiong(${arg})`//functionh最后一个函数可以接受多个参数consth=(...arg)=>`functionh(${arg.join('_')})`constr=compose(f,g,h)console.log(typeofr)//函数控制台。log(r(1,2,3))//Functionf(functiong(functionh(1_2_3)))从上面的代码可以看出,compose操作的结果是一个函数,通过调用传递的参数这个函数会作为compose最后一个参数的参数,从而像‘洋葱圈’一样由内向外一步步调用。sourcecodeexportdefaultfunctioncompose(...funcs){//funcs是一个数组,里面保存了所有参数函数//如果不传参数,则返回一个函数,就是输入什么,得到什么。if(funcs.length===0){returnarg=>arg}//当只传一个参数时,直接返回这个函数if(funcs.length===1){returnfuncs[0]}//返回compositionfunctionreturnfuncs.reduce((a,b)=>(...args)=>a(b(...args)))}这是对compose源码的整体解读,水平有限,欢迎拍砖。后续源码解读和测试示例可参考:redux源码解读仓库
