forEach & filter & map & reduce 原理

155 阅读2分钟

forEach 原理

使用 for 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._forEach = function (callback) {
  for (let i = 0; i < this.length; i++){
    callback(this[i], i, this)
  }
}

array._forEach((value, index, array) => {
  console.log(value, index, array)
})
/*
 稚名真白 0 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
 樱岛麻衣 1 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
 蝶祈 2 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
*/

使用 for in 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._forEach = function (callback) {
  for (let key in this) {
    if ('NaN' === (+key + '')) return
    callback(this[key], key, this)
  }
}

array._forEach((value, index, array) => {
  console.log(value, index, array)
})
/*
 稚名真白 0 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
 樱岛麻衣 1 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
 蝶祈 2 [ '稚名真白', '樱岛麻衣', '蝶祈' ]
*/

filter 原理

使用 for 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._filter = function (callback) {
  const res = []
  for (let i = 0; i < this.length; i++){
    callback(this[i], i, this) && res.push(this[i])
  }
  return res
}

const ゆずりはいのり = array._filter((value, index, array) => {
  return value === '蝶祈'
})

console.log(ゆずりはいのり) // [ '蝶祈' ]

使用 for in 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._filter = function (callback) {
  const res = []
  for (const key in this) {
    if ('NaN' === (+key + '')) return res
    callback(this[key], key, this) && res.push(this[key])
  }
}

const ゆずりはいのり = array._filter((value, index, array) => {
  return value === '蝶祈'
})

console.log(ゆずりはいのり) // [ '蝶祈' ]

map 原理

使用 for 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._map = function (callback) {
  const res = []
  for (let i = 0; i < this.length; i++){
    res.push(callback(this[i], i, this))
  }
  return res
}

const newArray = array._map((value, index, array) => {
  return index + '-' + value
})

console.log(newArray) // [ '0-稚名真白', '1-樱岛麻衣', '2-蝶祈' ]

使用 for in 实现

const array = ['稚名真白', '樱岛麻衣', '蝶祈']

Array.prototype._map = function (callback) {
  const res = []
  for (const key in this) {
    if ('NaN' === (+key + '')) return res
    res.push(callback(this[key], key, this))
  }
}

const newArray = array._map((value, index, array) => {
  return index + '-' + value
})

console.log(newArray) // ['0-稚名真白', '1-樱岛麻衣', '2-蝶祈']

reduce

使用 for 实现

const array = [2, 4, 6, 7, 8]

Array.prototype._reduce = function (callback, initValue) {
  if (Object.prototype.toString.call(callback) !== '[object Function]') {
    throw new Error('callback must be function')
  }

  // 判断是否传了初始值, 没有传就从下标1开始遍历,否则从下标0开始遍历
  let initIndex = arguments.length == 1 ? 1 : 0; 

  // 判断初始值,如果没传就默认取下标0的元素,否则取传过来的初始值为默认值
  let accumulator = initIndex ? this[0] : initValue

  for (let i = initIndex; i < this.length; i++) accumulator = callback(accumulator, this[i], i, this)
  return accumulator  
}

const res = array._reduce((accumulator, currentValue, currentIndex,  array) => {
  console.log(accumulator) // 10 14 30 66 115
  return accumulator += currentValue ** 2 // (10 + 2**2) (14 + 4**4) (30 + 6**6) (66 + 7**7) (115 + 8**8)
}, 10)

console.log(res) // 179

使用 for in 实现

const array = [2, 4, 6, 7, 8]

Array.prototype._reduce = function (callback, initValue) {
  if (Object.prototype.toString.call(callback) !== '[object Function]') {
    throw new Error('callback must be function')
  }

  // 判断是否传了初始值, 没有传就从下标1开始遍历,否则从下标0开始遍历
  let initIndex = arguments.length === 1 ? 1 : 0; 

  // 判断初始值,如果没传就默认取下标0的元素,否则取传过来的初始值为默认值
  let accumulator = initIndex ? this[0] : initValue

  for (const key in this) {
    if('NaN' === +key + '') return accumulator
    accumulator = callback(accumulator, this[key], key, this)
  }
}

const res = array._reduce((accumulator, currentValue, currentIndex,  array) => {
  console.log(accumulator) // 10 14 30 66 115
  return accumulator += currentValue ** 2 // 执行流程 -> (10 + 2**2) (14 + 4**4) (30 + 6**6) (66 + 7**7) (115 + 8**8)
}, 10)

console.log(res) // 179