学习理解数组的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 方法,可以通过像 for、for...of 和 for...in 这样的循环语句来实现提前终止。当不需要进一步迭代时,诸如 every()、some()、find() 和 findIndex() 等数组方法也会立即停止迭代。

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

相关推荐
总要学点什么4 小时前
第105篇:三维特效-流动图片墙体效果——让箭头沿墙长滚,它俩竟是同一份代码
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
Agent世界5 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
FungLeo5 小时前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
总要学点什么5 小时前
第104篇:三维特效-流动墙体效果——让贴图沿墙流动,它却只肯走一条对角线
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
某哈压力大6 小时前
SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了
前端·node.js·命令行
程序员大阳6 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半6 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳6 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
deli0076 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端
曦樂~7 小时前
【Web Development】03JavaScript 基础和事件
开发语言·前端·javascript