一、 Reduce的用法
reduce是一种数组运算,通常用于将数组的所有成员"累积"为一个值:

reduce
对数组arr
的每个成员执行sum
函数。sum
的参数a
是累积变量,参数b
是当前的数组成员。每次执行时,b
会加到a
,最后输出a
。
累积变量必须有一个初始值,上例是reduce
函数的第二个参数0
。如果省略该参数,那么初始值默认是数组的第一个成员。
相应api如下:

二、 reduce的本质
- 遍历
- 变形
- 累计
map是reduce的特例:累计变量的初始值也可以是一个数组

reduce包含了三种运算,因此非常有用。但也带来了一个问题:代码的复用性不高。在reduce里面,变形和累积是耦合的,不太容易拆分。
三、 reduce与redux中的compose函数

那么学习了reduce后,试着写个函数 能将多个函数进行组合成一个函数,也就是一元链式函数。例如:

使用reduce写一个函数,使这两个函数执行结果一样
代码实现如下:
function chained(funcs) {
return function(params){
return funcs.reduce(function(params, fn){ return fn(params) }, params);
}
}
验证如下:

研究一下redux中compose函数的实现:

这里需要注意的是:reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。
function chained(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => b(a(...args)))
}
另附loadsh compose函数实现源代码,了解一下。
var flow = function(funcs) {
var length = funcs.length
var index = length
while (index--) {
if (typeof funcs[index] !== 'function') {
throw new TypeError('Expected a function');
}
}
return function(...args) {
var index = 0
var result = length ? funcs[index].apply(this, args) : args[0]
while (++index < length) {
result = funcs[index].call(this, result)
}
return result
}
}
var flowRight = function(funcs) {
return flow(funcs.reverse())
}