如何实现数组方法forEach

121 阅读2分钟

forEach

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

语法

forEach(callbackFn)
forEach(callbackFn, thisArg)

参数

forEach()方法可接收两个参数,回调函数callbackFnthis的值thisArg(可选)

callbackFn被调用时传入以下参数:

element 数组正在处理的当前元素。 index 数组正在处理的当前元素的索引。 array 调用了forEach()的数组本身。

forEach原生使用

  • 常规使用
const nums = [23, 43, 12, 54, 76, 88, 34, 23, 12];
nums.forEach(function (value, index, arr) {
  console.log(value, index, arr);
  console.log(this);
})

运行结果如下图,不加第二个参数情况下执行回调函数的thiswindow

image.png

  • 加上第二个参数thisArg,执行callbackFn时用作this的值
nums.forEach(function (value, index, arr) {
  console.log(value, index, arr);
  console.log(this);
}, nums)

运行结果如下图,注意这里回调函数不能使用箭头函数

image.png

myForEach:实现forEach功能

还是使用这个数组

const nums = [23, 43, 12, 54, 76, 88, 34, 23, 12];

定义一个myForEach方法,传递一个回调函数fn,固定使用数组nums

function myForEach(fn) {
  for (let i = 0; i < nums.length; i++) {
    fn(nums[i], i, nums)
  }
}
// 调用myForEach,传入回调
myForEach(function(value, index, arr) {
  console.log(value, index, arr); // 这里就可以打印出我们想要的结果
})

功能已经实现,现在将这个方法挂载到Array的原型上,this表示当前调用该方法的数组。

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

使用

nums.myForEach(function(value, index, arr) {
  console.log(value, index, arr); // 按照预期输出
  console.log(this) // 此时的this还是指向window
})

下面就要添加第二个参数,实现设置回调函数中的this

修改原型方法myForEach,使用call改变回调的this指向,使其this指向第二个参数thisArg

Array.prototype.myForEach = function(fn, thisArg){ // 传递第二个参数thisArg
  for (let i = 0; i < this.length; i++) {
    fn.call(thisArg, this[i], i, this) // 修改this指向
  }
}

再次调用

nums.myForEach(function(value, index, arr) {
  console.log(value, index, arr);
  console.log(this)
}, nums)

输出如下结果:

image.png