学习理解数组的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 回调时,请确保你意识到这一点可能带来的影响。

相关推荐
绝世唐门三哥20 分钟前
vue3中页面返回时刷新首页的处理方案
开发语言·前端·javascript
sugar__salt23 分钟前
Node.js path 与 fs 核心模块完全指南 —— 从路径处理到异步流程控制
javascript·node.js
东方小月30 分钟前
agent-skills:把资深工程师的‘工作流’,装进你的AI编程里
前端·架构·代码规范
Maynor99632 分钟前
AI Coding 零基础实战教程|第五部分:完整项目案例实操
java·前端·人工智能·claude code·ai coding
binbin_5233 分钟前
React 井字棋教程:用一个小游戏理解组件和状态
前端·react.js·前端框架
梦曦i1 小时前
uni-router新推useUniEventChannel,彻底解决页面通信难题
前端·uni-app
柯克七七1 小时前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript
张元清2 小时前
React useObjectUrl Hook:预览文件与 Blob,不留内存泄漏(2026)
javascript·react.js
yuanlaile2 小时前
前端转 Flutter 自学完整规划,避开跨栈思维转换误区
前端·flutter·flutter跨平台开发
CN_HW2 小时前
Nginx 流量镜像配置文档-双轨国产化
服务器·前端·网络