手动重写数组方法forEach、map、filter、reduce、sort

lxf2023-02-17 01:52:39

持续创作,加速成长!这是我参与「AdminJS日新计划 · 10 月更文挑战」的第25天,点击查看活动详情

(1) Array.forEach

方法介绍

forEach()  方法对数组的每个元素执行一次给定的函数。

const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// "a" "b" "c"

forEach与普通的for循环功能几乎一致,唯一区别就是forEach无法使用return中断循环,需要用try catch 捕捉错误中断循环,而forEach可以使用return直接中断

参数要求

forEach(function(item, index, array) { /* … */ }, this)
  • item ,数组中正在处理的当前元素。

  • index , 数组中正在处理的当前元素的索引。

  • array ,forEach() 方法正在操作的数组。

  • thisArg ,可选参数。当执行回调函数 callback 时,用作 this 的值。

方法手写

Array.prototype.forEach = Array.prototype.forEach || function () {}
 const arr = [3, 5, 1]
 const o = { age: 18 }
 arr.forEach(function (item, index, originArr) {
    console.log(item, index, originArr, this)
  }, o) 

  Array.prototype.forEach2 = function (callback, _this = window) {
    // this => arr
    使用call来改变this指向
    for (let i = 0; i < this.length; i++) {
      callback.call(_this, this[i], i, this)
    }
  }
  arr.forEach2(function (item, index, originArr) {
    console.log(item, index, originArr, this)
  }, o)

(2) Array.map

方法介绍

map()  方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1);//[2, 8, 18, 32]

参数要求

map(function(item, index, array) { /* … */ }, this)
  • item ,数组中正在处理的当前元素。

  • index , 数组中正在处理的当前元素的索引。

  • array ,map() 方法正在操作的数组。

  • thisArg ,可选参数。当执行回调函数 callback 时,用作 this 的值。

返回值

一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

方法手写

  Array.prototype.map2 = function (callback) {
    const arr = []
    for (let i = 0; i < this.length; i++) {
      arr.push(callback(this[i], i, this))
    }
    return arr
  }
  const newArr = arr.map2((item, index, originArr) => {
    return `~${item}~`
  }) 

(3) Array.filter

方法介绍

filter()  方法创建给定数组一部分的浅拷贝 (en-US),其包含通过所提供函数实现的测试的所有元素。


const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(item => item.length > 6);

console.log(result);// ["exuberant", "destruction", "present"]

filter(function(item, index, array) { /* … */ }, this)
  • item ,数组中正在处理的当前元素。

  • index , 数组中正在处理的当前元素的索引。

  • array ,filter() 方法正在操作的数组。

  • thisArg ,可选参数。当执行回调函数 callback 时,用作 this 的值。

返回值

一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

方法手写

  Array.prototype.filter2 = function (callback) {
    const arr = []
    for (let i = 0; i < this.length; i++) {
      if (callback(this[i], i, this)) {
        arr.push(this[i])
      }
    }
    return arr
  }
  const newArr = arr.filter2((item, index, originArr) => {
    // 当整体结果是 true 的时候,把 item 怼到新数组
    return item > 3
  })
  console.log(newArr) 

(4) Array.reduce

方法介绍

reduce() 对排列中的每一个元素的每一个元素都由您提供的每一次按还原函数的方法,作为降低元素的计算结果的结果,执行顺序将其汇总结果,最终将其汇总为一个返回值。

如果第一次执行指标值开始执行时,不存在“上一次指标计算”的结果。而不是执行器的第二个元素开始值(而不是执行器的初始值为0)。

const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const i = 0;
const sum = array1.reduce(
  (previousValue, currentValue) => previousValue + currentValue,
  i
);

console.log(sum);
//  10

参数要求

reduce(function(sum, item, index, array) { /* … */ }, initialValue)
  • sum:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]

  • item:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]

  • index:数组中正在处理的元素的索引。若指定了初始值 initialValue,则起始索引号为 0,否则从索引 1 起始。

  • array:用于遍历的数组。

  • initialValue, 可选参数。作为第一次调用 callback 函数时参数 item 的值。若指定了初始值 initialValue,则 item 则将使用数组第一个元素;否则 item 将使用数组第一个元素,而 item 将使用数组第二个元素。

返回值

使用“reducer”回调函数遍历整个数组后的结果。

方法手写

  // reduce
  const arr = [3, 5, 1]
  // acc 和 cur 在初始循环的时候有两种取值
  // 传递了初始值
  // acc => 初始值,cur => 数组的第 1 项
  // 没有传递初始值
  // acc => 数组的第 1 项,cur => 数组的第 2 项

  Array.prototype.reduce2 = function (reducer, acc) {
    let startIndex = 0
    // 没有传递初始值
    // acc => 数组的第 1 项,cur => 数组的第 2 项
    if (acc === undefined) {
      startIndex = 1
      acc = this[0]
    }
    // 传递了初始值
    for (let i = startIndex; i < this.length; i++) {
      acc = reducer(acc, this[i], i, this)
    }
    return acc
  }
  /* const r = arr.reduce2((acc, cur, curIndex, originArr) => acc + cur, 0)
  console.log(r) */

  let arr2 = [
    {
      num: 5,
    },
    {
      num: 1,
    },
    {
      num: 4,
    },
  ]

  console.log(arr2.reduce2((acc, cur) => acc + cur.num, 0))

手动重写数组方法forEach、map、filter、reduce、sort