js中数组forEach方法的使用及实现

js中数组forEach方法的使用及实现

首先来看下mdn中的介绍

描述

forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过。(说白了就是去循环数组中的元素,每循环一次就调用一次传入的函数。并且在被调用时,不会改变原数组)

语法

arr.forEach(callback(currentValue [, index [, arrSelf]])[, thisArg])

参数描述

callback
为数组中每个元素执行的函数,该函数接收一至三个参数:
(1)currentValue
数组中循环的当前元素。
(2)index 可选
数组中正在处理的当前元素的索引。
(3)arrSelf 可选
当前调用forEach() 方法的数组对象本身。

thisArg 可选
可选参数。当执行回调函数 callback 时,改变回调函数 this 的指向。(如果不传入或者为null,则采用原来的this指向,如果传入则每次调用callback函数时将函数的this指向thisArg参数)

返回值

undefined。

使用

    let arrList = [1, 3, 5, 9]
    // 不传入thisArg参数时
    arrList.forEach(function(currentValue , index, arrSelf) {
      console.log(currentValue , index, arrSelf, this)
    })
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] Window
    // 3 1 [1, 3, 5, 9] Window
    // 5 2 [1, 3, 5, 9] Window
    // 9 3 [1, 3, 5, 9] Window

    // 传入thisArg参数时
    arrList.forEach(function(currentValue , index, arrSelf) {
      console.log(currentValue , index, arrSelf, this)
    }, {a: 9})
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] {a: 9}
    // 3 1 [1, 3, 5, 9] {a: 9}
    // 5 2 [1, 3, 5, 9] {a: 9}
    // 9 3 [1, 3, 5, 9] {a: 9}

    // 当传入的callback为箭头函数时
    arrList.forEach((currentValue , index, arrSelf) => {
      console.log(currentValue , index, arrSelf, this)
    }, {a: 9})
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] Window
    // 3 1 [1, 3, 5, 9] Window
    // 5 2 [1, 3, 5, 9] Window
    // 9 3 [1, 3, 5, 9] Window

上述代码演示了forEach方法的使用,打印出了每个传入的参数,注意的是当传入的callback函数为箭头函数时,thisArg参数就不起作用了,是因为箭头函数没有自己的this,并且不可以被改变,此时的this会去向上找它所在作用域的this。下面根据上面描述和使用模拟实现自己的forEach方法:

步骤思路

1、在array原型上添加自己的forEach方法
2、传入所需要的参数
3、使用for循环进行循环数组
4、利用call方法改变回调函数this指向
5、调用回调函数

实现代码

    Array.prototype.myForEach = function(callback, thisAry) {
      // 循环数组,利用call方法调用传入的回调函数并改变它的this指向
      for (let index = 0; index < this.length; index++) {
        callback.call(thisAry, this[index], index, this)
      }
    }

测试验证

    Array.prototype.myForEach = function(callback, thisAry) {
      // 循环数组,利用call方法调用传入的回调函数并改变它的this指向
      for (let index = 0; index < this.length; index++) {
        callback.call(thisAry, this[index], index, this)
      }
    }
    let arrList = [1, 3, 5, 9]

    // 不传入thisArg参数时
    arrList.myForEach(function(currentValue , index, arrSelf) {
      console.log(currentValue , index, arrSelf, this)
    })
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] Window
    // 3 1 [1, 3, 5, 9] Window
    // 5 2 [1, 3, 5, 9] Window
    // 9 3 [1, 3, 5, 9] Window

    // 传入thisArg参数时
    arrList.myForEach(function(currentValue , index, arrSelf) {
      console.log(currentValue , index, arrSelf, this)
    }, {a: 9})
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] {a: 9}
    // 3 1 [1, 3, 5, 9] {a: 9}
    // 5 2 [1, 3, 5, 9] {a: 9}
    // 9 3 [1, 3, 5, 9] {a: 9}

    // 当传入的callback为箭头函数时
    arrList.myForEach((currentValue , index, arrSelf) => {
      console.log(currentValue , index, arrSelf, this)
    }, {a: 9})
    // 打印结果如下
    // 1 0 [1, 3, 5, 9] Window
    // 3 1 [1, 3, 5, 9] Window
    // 5 2 [1, 3, 5, 9] Window
    // 9 3 [1, 3, 5, 9] Window

打印结果和原生方法一致。

上一篇:js数组基本类型去重3种方法


下一篇:JavaScript基础——内置对象(数组对象)