从0开始阅读Redux源码 - compose

157 阅读2分钟

1.前言

compose的源码较少,但是里面却有很多值得我们学习的地方,首先先介绍下数组的方法之一reduce。 这里先贴几个链接关于reduce的。这俩篇对我下面提到的initialValue是否提供有着很详细的描述。

博客园 ES5 数组方法reduce

MDN Array.prototype.reduce()

2.Reduce

a.用法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

b.参数介绍

total:累加器值
currentValue:数组遍历时当前值
currentIndex:数组遍历时当前索引
arr:当前遍历的数组
initialValue:作为累加器的初始值,这里需要注意的是,如果不赋该值的话,那么total的初始值就是arr[0]

c.说明

reduce执行时对数组中每一项元素执行传入的callback,参数分别为total, currentValue, currentIndex, arr。 当第一次执行时,如果initialValue提供的话,那么total=initialValue,并且从数组的第1位元素开始遍历。 如果initialValue没有提供的话,那么total=arr[0],并且从数组的第2位元素开始遍历。

注:每次遍历处理后需要return new total作为下一次遍历的total值

d.实例

(1)数组之和

arr.reduce((total, currentValue) => { return total + currentValue }, 0)

等价于arr.reduce((total, currentValue) => { return total + currentValue })(不传initialValue)

(2)反转对象的键值对key和value(最近项目里自己用的^-^)

obj = { a: 1, b: 2, c: 3 }

Object.keys(obj).reduce((total, currentValue) => {

total[obj[currentValue]] = currentValue;
return total;

}, {})

其他有很多用法,自己在实践中多使用吧。

3.Compose

重点来了,Compose就是用reduce来实现的。

compose实现这样的功能:
compose(f,g) -> (..args) => f(g(...args))
compose(f,g,h) -> (..args) => f(g(h(...args)))

compose主要用在redux中间件,applyMiddleware函数用到compose,applyMiddleware后面我再说。

首先我们看compose(f,g),前面说到initialValue没有提供的话,那么funcs.reduce((a, b) => (...args) => a(b(...args)))


第一次遍历的时候a=f, b=g, 返回的就是函数(...args) => f(g(...args)). 然后我们再看compose(f,g,h),为了便于区分,第一次返回的结果我们令 k = (...arr) => f(g(...arr))


第二次遍历则为(k,h) => (...args) => k(h(...args)),这里...arr 就是h(...args),然后替换进来。就成了f(g(h(...args)))。

一开始我也不是很理解这里,琢磨了好一会才明白。主要就是我上面提到不传initialValue的话,total=arr[0], currentValue=arr[1]。理解了这个地方,你就会对reduce的使用更加熟练,原先我也不怎么使用这个函数,其实还是很好用的。

4.总结

学习的过程中多思考,多看源码还是有好处的。对一个问题不了解,那么就拆开几个部分,一个一个去理解,那么问题自然就解开了。