如何实现自己的reduce方法

3,632 阅读1分钟

reduce()方法是ECMAScript5规范中出现的数组方法,该方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

// 语法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组)

initialValue:传递给函数的初始值,当initialValue有值时,将作为accumulator传入回调函数中。

reduce方法的使用

// 求和
const sum = [1,2,3,4].reduce(function(prev, next, currentIndex, array){
    return prev + next;
});
console.log(sum) // 10 
// 求平均数
const average = [1,2,3,4].reduce(function(prev, next, currentIndex, array){
    if (currentIndex === array.length - 1) {
        return (prev+next)/array.length;
    }
    return prev + next;
});
console.log(average) // 2.5
// 求总价格
const goodsList = [
    {price: 10},
    {price: 20},
    {price: 30}
];

const total = goodsList.reduce(function(prev, next, currentIndex, array){
    // prev代表的是上一次return的结果
    // 可能存在有的小伙伴跟我当初一样使用return prev.price + next.price的情况
    return prev + next.price;
}, 0);

console.log(total); // 60

reduce方法的实现

Array.prototype.myReduce = function(fn, initialValue) {
    for(let i=0; i<this.length; i++) {
        if (typeof initialValue === 'undefined') {
            initialValue = fn(this[i], this[i+1], i+1, this);
            ++i;
        } else {
            initialValue = fn(initialValue, this[i], i, this);
        }
    }
    return initialValue;
}
// 为了方便测试,我把上面代码copy过来
// 求和
const sum = [1,2,3,4].myReduce(function(prev, next, currentIndex, array){
    return prev + next;
});
console.log(sum) // 10 
// 求平均数
const average = [1,2,3,4].myReduce(function(prev, next, currentIndex, array){
    if (currentIndex === array.length - 1) {
        return (prev+next)/array.length;
    }
    return prev + next;
});
console.log(average) // 2.5
// 求总价格
const goodsList = [
    {price: 10},
    {price: 20},
    {price: 30}
];

const total = goodsList.myReduce(function(prev, next, currentIndex, array){
    // prev代表的是上一次return的结果
    // 可能存在有的小伙伴跟我当初一样使用return prev.price + next.price的情况
    return prev + next.price;
}, 0);

console.log(total); // 60