Array.prototype.forEach()
Runs a function once for each array element, for its side effects only.
forEach(callbackFn)
forEach(callbackFn, thisArg)- Added in JavaScript ES5 (2009)
Parameters
| Parameter | Type | Description |
|---|---|---|
$callbackFn | Function | Function run for each element, called with (element, index, array). Its return value is discarded. |
$thisArgoptional | any= undefined | Value to use as this when executing callbackFn. Ignored by arrow functions. |
Return value
undefinedAlways undefined — forEach() is not chainable.
Errors
Nothing of its own — throwing from callbackFn is the only way to abort the loop, and the error propagates to the caller.
forEach() exists for side effects: logging, pushing into an external structure, mutating objects in place. It returns undefined, so it is the end of a chain, never the middle of one. If you want a value back, that is a signal to use map(), filter() or reduce().
You cannot break out of it
There is no early exit. return inside the callback only ends that one invocation — the loop keeps going, which is the single most common surprise. break and continue are syntax errors there. When you need to stop early, use for...of, or pick a method whose job is to stop: find(), findIndex(), some(), every(). Throwing an exception works but should stay a last resort.
Async callbacks do not await
forEach() ignores what the callback returns, so an async callback produces a Promise that nobody waits on. The loop finishes immediately and the following line runs before any of the work does. Use for...of with await for sequential work, or Promise.all(arr.map(fn)) for parallel work.
Example
When to use it
- Log or report each item in a collection during debugging
- Attach a computed property to every object in an existing array
- Push entries into a Map or Set built outside the loop
- Fire off a side effect per element where no result is collected
Frequently asked questions
How do I break out of a forEach loop?
You can't — the only escape is throwing an exception. Use for...of with break, or switch to some() / every() / find() / findIndex(), which stop as soon as the callback tells them to.
What does forEach() return?
Always undefined, no matter what the callback returns. That makes it unchainable, so if you find yourself wanting to chain, use map() or filter() instead.
Should I use forEach() or for...of?
Use for...of when you need break, continue, or await; use forEach() when you want the index alongside the value and a self-contained callback. Speed is rarely the deciding factor: for...of does not avoid a per-element function call — it invokes the array iterator's next() on every pass — and engines typically make forEach() at least as fast.
More examples
return does not break the loop
Both print only 1 and 2, but for very different reasons. forEach still called the callback for 3, 4 and 5 and simply skipped the log; for...of actually stopped at 3. On a large array or an expensive predicate, that difference matters.
const nums = [1, 2, 3, 4, 5];
nums.forEach((n) => {
if (n > 2) return;
console.log("forEach", n);
});
for (const n of nums) {
if (n > 2) break;
console.log("for...of", n);
}Async callbacks are not awaited
The first log prints [] — forEach discarded the three Promises and moved on before any of them resolved. The map + Promise.all version prints ['done 1', 'done 2', 'done 3'], because those Promises are collected and awaited.
const ids = [1, 2, 3];
const log = [];
ids.forEach(async (id) => {
await null;
log.push("done " + id);
});
console.log(log);
console.log(await Promise.all(ids.map(async (id) => "done " + id)));
Discussion