对于reduce,可能以前对于他的用法只是用于累加,但其实他的真正用途适用于做为一个高阶函数,用于实现函数式编程里的 compose编程
建立一个函数,最少接收两个参数,一个函数数组,一个初始参数,依次执行函数数组,下一个函数的第一个参数是上一个的结果,初始参数是第一个函数的第一个参数。数组
<!-- 接收4个参数,第一个是要执行的数组,第二个是回调函数,第三个是初始参数,第4个是是否跳过第一个回调并拿第一个参数当作下一个回调的参数 --> function reduce(collection, iteratee, accumulator) { const func = Array.isArray(collection) ? arrayReduce : baseReduce const initAccum = arguments.length < 3 <!-- baseEach是当collection不是数组时的实现 --> return func(collection, iteratee, accumulator, initAccum, baseEach) }
function arrayReduce(array, iteratee, accumulator, initAccum) { let index = -1 const length = array == null ? 0 : array.length if (initAccum && length) { accumulator = array[++index] } // 当initAccum为true时,从下标为1的开始运行 while (++index < length) { accumulator = iteratee(accumulator, array[index], index, array) } return accumulator }
<!-- 当collection是对象时的实现 --> function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { eachFunc(collection, (value, index, collection) => { accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index, collection) }) return accumulator }
<!-- 对collection是不一样类型的处理 --> function baseEach(collection, iteratee) { if (collection == null) { return collection } <!-- 判断是否是很是规的Array,例如arguments --> if (!isArrayLike(collection)) { <!-- 这里的具体就是跑了个for --> return baseForOwn(collection, iteratee) } const length = collection.length const iterable = Object(collection) let index = -1 while (++index < length) { <!-- 这里的具体就是跑了个for,initAccum为true时第一次跳过 --> if (iteratee(iterable[index], index, iterable) === false) { break } } return collection }