對於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 }