学习理解数组的forEach方法

数组的forEach方法

1.语法

MDN中对 Arrary.prototype.forEach()的语法解释为:

js 复制代码
forEach(callbackFn)
forEach(callbackFn, thisArg)

结合我们已经使用过forEach方法来理解

js 复制代码
const array1 = ['a', 'b', 'c'];
array1.forEach((element, index, arrary) =>{
    console.log('第===>',index,'个====>',element )
});
​
​
function funcA(element, index, arrary){
    console.log('第===>',index,'个====>',element  )
}

callbackFn

从上面代码块将箭头函数理解为一个整体,那么funcA就是callbackFn,它是数组每个元素执行的函数,并会丢弃它的返回值,该函数被调用时将传入以下参数:

  • element 数组正在处理的当前元素
  • index 数组正在处理的当前元素的索引
  • arrary 调用forEach的数组本身

thisArg

执行callbackFn时用做this的值。

这样说可能很模糊,举个例子:

js 复制代码
 var name = "window";
const myObject = {
    name: "John",
    fruits: ["apple", "banana", "cherry"],
    printFruits: function () {
        this.fruits.forEach(function (fruit) {
            console.log(this.name + " likes " + fruit);
        }, window); // 通过传递 `this` 参数指定回调函数的 `this` 值为window
        this.fruits.forEach(function (fruit) {
            console.log(this.name + " likes " + fruit);
        }, this); // 通过传递 `this` 参数指定回调函数的 `this` 值为当前对象
    },
};
myObject.printFruits();
​
// window likes apple
// window likes banana
// window likes cherry
​
//John likes apple·
//John likes banana
//John likes cherry

当你传递了 thisArg 参数时,回调函数中的 this 将指向 thisArg 参数所代表的值。如果不传递 thisArg 参数,默认情况下 this 的值将是 undefined(在严格模式下),或者是全局对象(在非严格模式下)。

如上,如果我们在forEach的第二个参数内传入window,那么在forEach内的回调函数callbackFn 内执行的this便是 window对象,寻找到的name 就是window

通过使用 thisArg 参数,我们可以在 forEach 方法中明确指定回调函数的 this 值,以确保在回调函数中能够正确地访问和操作相关的对象或上下文。

返回值

undefined

2.描述

  1. forEach 方法是一个迭代方法。它按照索引 升序 地为数组中的每个元素调用一次提供的 callbackFn函数。
  2. callbackFn仅对已赋值的数组索引调用,对于稀疏数组中的空槽,它不会调用
ini 复制代码
// 稀疏函数
const data = ["a", "", "c", "d"];
  1. callbackFn会改变原数组,但是在第一次调用 callbackFn之前,数组的长度已经被保存了。
  • A 当调用 forEach() 时,callbackFn 不会访问超出数组初始长度的任何元素。
  • B 已经访问过的索引的更改不会导致 callbackFn 再次调用它们。
  • C 如果 callbackFn 更改了数组中已经存在但尚未访问的元素,则传递给 callbackFn 的值将是在访问该元素时的值。已经被删除的元素不会被访问。
js 复制代码
const arr = [1, 2, 3];
  arr.forEach((item, index,arr1) => {
    console.log("🚀", arr1)
    arr.splice(index,1);
  });

3.实现步骤

forEach的实现是怎么样的一个实现步骤呢?

通过查看 ECMAScript 规范。

我们通过代码来实现官方的步骤

js 复制代码
const arr1 = [1, 2, 3];
Array.prototype.forEach = function (callback) {
    const len = this.length;
    if (typeof callback !== "function") {
      throw new TypeError(callback + "is no function");
    }
    let k = 0;
    while (k < len) {
      if (k in this) {
        callback(this[k], k, this);
          }
      k++
    }
};
arr1.forEach( (item,i,arr) =>{
    arr.splice(i,1)
    console.log(item);
})

4.使用

  1. forEach 的方法是通用的,它只期待this 值具有length 属性和整数键的属性。

    js 复制代码
    //所以在对象内使用forEach 会出现
    const arrayLike = {
      length: 3,
      0: 2,
      1: 3,
      2: 4,
    };
    Array.prototype.forEach.call(arrayLike, (x) => console.log(x));
    // 2
    // 3
    // 4
    //因为forEach它只期待`this` 值具有`length` 属性和整数键的属性。
  2. 除非抛出异常,否则没有办法停止或中断 forEach 循环,如果有这样的需求,则不应该使用forEach 方法,可以通过像 forfor...offor...in 这样的循环语句来实现提前终止。当不需要进一步迭代时,诸如 every()some()find()findIndex() 等数组方法也会立即停止迭代。

  3. forEach() 期望的是一个同步函数,它不会等待 Promise 兑现。在使用 Promise(或异步函数)作为 forEach 回调时,请确保你意识到这一点可能带来的影响。

相关推荐
newxtc1 分钟前
【爱给网-注册安全分析报告-无验证方式导致安全隐患】
前端·chrome·windows·安全·媒体
一个很帅的帅哥18 分钟前
axios(基于Promise的HTTP客户端) 与 `async` 和 `await` 结合使用
javascript·网络·网络协议·http·async·promise·await
dream_ready1 小时前
linux安装nginx+前端部署vue项目(实际测试react项目也可以)
前端·javascript·vue.js·nginx·react·html5
编写美好前程1 小时前
ruoyi-vue若依前端是如何防止接口重复请求
前端·javascript·vue.js
flytam1 小时前
ES5 在 Web 上的现状
前端·javascript
喵喵酱仔__1 小时前
阻止冒泡事件
前端·javascript·vue.js
GISer_Jing1 小时前
前端面试CSS常见题目
前端·css·面试
某公司摸鱼前端1 小时前
如何关闭前端Chrome的debugger反调试
javascript·chrome
八了个戒1 小时前
【TypeScript入坑】什么是TypeScript?
开发语言·前端·javascript·面试·typescript
不悔哥2 小时前
vue 案例使用
前端·javascript·vue.js