JavaScript forEach:逐项执行回调
JavaScript 数组 forEach(Array.prototype.forEach)会按索引顺序对数组中的每个元素执行一次回调。当你只需要副作用(例如日志输出、DOM 更新或更新外部变量)而不需要 break 或 await 时,适合使用 JavaScript forEach 循环。由于它返回 undefined,所以不适合做转换(map)或可提前停止的查找(find、some)。需要流程控制时,优先使用 for...of 循环。
JavaScript forEach 数组迭代示例
输出:
输出将显示在这里...
输出:
0: 红色
1: 绿色
2: 蓝色
这个示例如何工作
colors数组里有三个字符串。forEach对每个元素调用一次箭头函数,并把当前元素和从 0 开始的索引作为参数传入。- 回调会输出每个颜色及其位置。
forEach按索引升序处理元素,并会跳过稀疏数组中的空槽。
forEach 的常见陷阱
在 forEach 中使用 async/await:
错误写法:
const urls = ["https://example.com/a", "https://example.com/b"];
urls.forEach(async (url) => {
await fetch(url);
});
console.log("完成"); // 会立即执行
正确写法:
for (const url of urls) {
await fetch(url);
}
forEach 不会等待回调返回的 Promise。串行 await 用 for...of;并行任务用 await Promise.all(urls.map((url) => fetch(url)))。
尝试在 forEach 中提前退出:
错误写法:
const items = ["a", "b", "c"];
const target = "b";
items.forEach((item) => {
if (item === target) break; // SyntaxError
});
正确写法:
const found = items.find((item) => item === target);
forEach 不能提前退出。短路查找用 find/some,需要 break 时用 for...of。
forEach vs map vs for…of
| 特性 | forEach | map | for...of |
|---|---|---|---|
| 返回值 | undefined | 新数组 | —(循环) |
| 提前退出 | 否 | 否 | break / return |
对 await 友好 | 否 | 配合 Promise.all | 是 |
| 最适合 | 副作用 | 数据转换 | 流程控制 |
不需要提前退出和 await 时,用 forEach 处理副作用。目标是得到转换后的数组时,用 map。需要 break、continue 或串行 await 时,用 for...of。
FAQ
可以提前跳出 JavaScript forEach 吗?
不能。forEach 会对每个元素执行回调。抛异常可以中断迭代,但这是反模式。应使用带 break 的 for...of,或使用 find/some/every 做短路查找。
forEach 会修改原数组吗?
forEach 本身不会修改数组。回调里可以原地修改对象元素,因为传入的是引用而不是副本。数字和字符串等原始值按值传递,不能通过回调参数直接修改。
forEach 和 map 的区别是什么?
forEach 返回 undefined,设计目标是副作用。map 会基于回调返回值构建并返回一个新数组。目标是转换数据时用 map;目标是执行日志输出或 DOM 更新等动作时用 forEach。