Array.prototype.forEach()
基线 广泛可用
此功能非常成熟,可在许多设备和浏览器版本上运行。它从 2015 年 7 月.
报告反馈
试一试
语法
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。forEach(callbackFn)
forEach(callbackFn, thisArg)
js
参数
-
callbackFn
要对数组中的每个元素执行的函数。它的返回值被丢弃。该函数使用以下参数调用
-
element
数组中正在处理的当前元素。
-
index
数组中正在处理的当前元素的索引。
-
array
- 调用
forEach()
的数组。 -
thisArg
可选
在执行 callbackFn
时用作 this
的值。请参阅 迭代方法。
返回值
描述
无 (undefined
).
forEach()
方法是一个 迭代方法。它对数组中的每个元素按升序索引调用提供的 callbackFn
函数一次。与 map()
不同,forEach()
始终返回 undefined
且不可链式调用。典型用例是在链条末尾执行副作用。阅读 迭代方法 部分以获取有关这些方法在一般情况下如何工作的更多信息。
callbackFn
仅针对具有已分配值的数组索引调用。它不会针对 稀疏数组 中的空插槽调用。
forEach()
方法是 泛型 的。它只期望 this
值具有 length
属性和整数键属性。
除了抛出异常之外,没有办法停止或中断 forEach()
循环。如果您需要这种行为,forEach()
方法不是合适的工具。
可以使用像 for
、for...of
和 for...in
这样的循环语句来实现提前终止。像 every()
、some()
、find()
和 findIndex()
这样的数组方法在进一步迭代变得不必要时也会立即停止迭代。
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const ratings = [5, 4, 5];
let sum = 0;
const sumFunction = async (a, b) => a + b;
ratings.forEach(async (rating) => {
sum = await sumFunction(sum, rating);
});
console.log(sum);
// Naively expected output: 14
// Actual output: 0
forEach()
期望同步函数 - 它不会等待 Promise。在使用 Promise(或 async 函数)作为 forEach
回调时,请确保您了解其影响。
示例
要按顺序或并发地运行一系列异步操作,请参阅 Promise 组合。
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const items = ["item1", "item2", "item3"];
const copyItems = [];
// before
for (let i = 0; i < items.length; i++) {
copyItems.push(items[i]);
}
// after
items.forEach((item) => {
copyItems.push(item);
});
将 for 循环转换为 forEach
打印数组的内容
注意:为了在控制台中显示数组的内容,您可以使用 console.table()
,它会打印数组的格式化版本。
以下示例说明了另一种方法,使用 forEach()
。
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const logArrayElements = (element, index /*, array */) => {
console.log(`a[${index}] = ${element}`);
};
// Notice that index 2 is skipped, since there is no item at
// that position in the array.
[2, 5, , 9].forEach(logArrayElements);
// Logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9
以下代码为数组中的每个元素记录一行
使用 thisArg
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。class Counter {
constructor() {
this.sum = 0;
this.count = 0;
}
add(array) {
// Only function expressions have their own this bindings.
array.forEach(function countEntry(entry) {
this.sum += entry;
++this.count;
}, this);
}
}
const obj = new Counter();
obj.add([2, 5, 9]);
console.log(obj.count); // 3
console.log(obj.sum); // 16
以下(人为的)示例从数组中的每个条目更新对象的属性
由于将 thisArg
参数 (this
) 传递给 forEach()
,因此它在每次调用时都会传递给 callback
。回调使用它作为其 this
值。
注意:如果传递的回调函数使用了 箭头函数表达式,则可以省略 thisArg
参数,因为所有箭头函数都会从词法上绑定 this
值。
对象复制函数
以下代码创建给定对象的副本。
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const copy = (obj) => {
const copy = Object.create(Object.getPrototypeOf(obj));
const propNames = Object.getOwnPropertyNames(obj);
propNames.forEach((name) => {
const desc = Object.getOwnPropertyDescriptor(obj, name);
Object.defineProperty(copy, name, desc);
});
return copy;
};
const obj1 = { a: 1, b: 2 };
const obj2 = copy(obj1); // obj2 looks like obj1 now
有不同的方法可以创建对象的副本。以下只是其中一种方法,旨在通过使用 Object.*
实用程序函数来解释 Array.prototype.forEach()
的工作原理。
展平数组
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const flatten = (arr) => {
const result = [];
arr.forEach((item) => {
if (Array.isArray(item)) {
result.push(...flatten(item));
} else {
result.push(item);
}
});
return result;
};
// Usage
const nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]];
console.log(flatten(nested)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
以下示例仅用于学习目的。如果您想使用内置方法展平数组,可以使用 Array.prototype.flat()
。
使用 callbackFn 的第三个参数
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const numbers = [3, -1, 1, 4, 1, 5];
numbers
.filter((num) => num > 0)
.forEach((num, idx, arr) => {
// Without the arr argument, there's no way to easily access the
// intermediate array without saving it to a variable.
console.log(arr[idx - 1], num, arr[idx + 1]);
});
// undefined 3 1
// 3 1 4
// 1 4 1
// 4 1 5
// 1 5 undefined
array
参数在您想要访问数组中的另一个元素时很有用,尤其是在您没有引用该数组的现有变量时。以下示例首先使用 filter()
提取正值,然后使用 forEach()
记录其邻居。
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const arraySparse = [1, 3, /* empty */, 7];
let numCallbackRuns = 0;
arraySparse.forEach((element) => {
console.log({ element });
numCallbackRuns++;
});
console.log({ numCallbackRuns });
// { element: 1 }
// { element: 3 }
// { element: 7 }
// { numCallbackRuns: 3 }
对稀疏数组使用 forEach()
回调函数不会针对索引 2 处的缺失值调用。
对非数组对象调用 forEach()
forEach()
方法在 Array
实例上执行一个提供的函数,对每个数组元素执行一次。const arrayLike = {
length: 3,
0: 2,
1: 3,
2: 4,
3: 5, // ignored by forEach() since length is 3
};
Array.prototype.forEach.call(arrayLike, (x) => console.log(x));
// 2
// 3
// 4
规范
forEach() 方法读取 this 的 length 属性,然后访问其键为小于 length 的非负整数的每个属性。 |
---|
规范 # ECMAScript 语言规范 |
浏览器兼容性
sec-array.prototype.foreach