数组的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.描述
- forEach 方法是一个迭代方法。它按照索引 升序 地为数组中的每个元素调用一次提供的
callbackFn
函数。 callbackFn
仅对已赋值的数组索引调用,对于稀疏数组中的空槽,它不会调用
ini
// 稀疏函数
const data = ["a", "", "c", "d"];
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.使用
-
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` 属性和整数键的属性。
-
除非抛出异常,否则没有办法停止或中断
forEach
循环,如果有这样的需求,则不应该使用forEach
方法,可以通过像for
、for...of
和for...in
这样的循环语句来实现提前终止。当不需要进一步迭代时,诸如every()
、some()
、find()
和findIndex()
等数组方法也会立即停止迭代。 -
forEach()
期望的是一个同步函数,它不会等待 Promise 兑现。在使用 Promise(或异步函数)作为forEach
回调时,请确保你意识到这一点可能带来的影响。