语法:array.reduce(callback, [initialValue])
reduce()方法接收callback函数,
function callback(preValue, curValue, index, array)

preValue: 上一次调用回调返回的值,活着初始值(initialValue)

curValue: 数组中当前被处理的数组项

index: 当前数组项在数组中的索引值

array: 调用reduce()方法的数组

initialValue: 第一次调用callback函数时的preValue

原理

Array.prototype.myReduce = function(callback, prev){
  for(let i = 0; I < this.length; i ++){
    // 如果没有传默认值,即当第一次循环,prev为undefined的时候,初始值是数组第一项,索引是1
    if(typeof prev === 'undefined'){
        prev = callback(this[i], this[i + 1], i, this)
        ++ i
    } else {
        prev = callback(prev, this[i],  i, this)
    }
  }
  return prev
}
let arr = [1, 2, 3, 4, 5].myReduce((prev, cur, index, array) => {
  return prev + cur
})
console.log(arr)      // 15

应用:
1、数组求和

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce((prev, cur, index, ary) => {
  return prev + cur
})
arr    // 55

2、数组求阶乘

  let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce((prev, cur, index, ary) => {
  return prev * cur
})
arr     // 3628800

3、展平数组(二维数组变一维数组)

let flat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].reduce((prev, cur, index, array) => {
  return [...prev, ...cur]
})
flat    // [1, 2, 3, 4, 5, 6, 7, 8]

4、 数组去重

  let arr = [1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 4, 6, 4, 3, 2].sort().reduce((prev, cur, index, array) => {
    if(prev.length === 0 || prev[prev.length -1] !== cur){
      prev.push(cur)
    }
    return prev
}, [])
arr         // [ 1, 2, 3, 4, 5, 6 ]