map() vs forEach()
map() transforms each element and returns a NEW array. forEach() executes a side effect for each element and returns undefined.
Side-by-Side Comparison
| Feature | Array.map() | Array.forEach() |
|---|---|---|
| Return value | New array | undefined |
| Purpose | Transform data | Execute side effects |
| Chainable | Yes | No |
| Original array | Not mutated | Not mutated (but callbacks may mutate) |
| Break early | No (use for...of) | No (use for...of) |
Code Examples
Array.map()
- Returns a NEW array with transformed elements
- Does NOT mutate the original array
- Each callback return value becomes an element in the new array
- Chainable — can call .filter(), .reduce() etc. after
const numbers = [1, 2, 3, 4]
const doubled = numbers.map(n => n * 2)
// doubled: [2, 4, 6, 8]
// numbers: [1, 2, 3, 4] (unchanged)
// Chainable
const result = numbers
.map(n => n * 2)
.filter(n => n > 4)
// result: [6, 8]Array.forEach()
- Returns undefined — cannot chain
- Used for SIDE EFFECTS (logging, DOM updates, mutations)
- Does NOT create a new array
- Cannot break or return early (use for...of instead)
const numbers = [1, 2, 3, 4]
// Side effect: logging
numbers.forEach(n => console.log(n))
// Side effect: DOM manipulation
items.forEach(item => {
document.body.appendChild(
createItemElement(item)
)
})
// Returns undefined — can't chain!
// numbers.forEach(...).filter(...) // TypeErrorWhen to Use Which
Array.map()
When you need a transformed version of the data — converting formats, extracting properties, computing derived values. The functional programming choice.
Array.forEach()
When you need to DO something with each element without producing a new array — logging, API calls, DOM updates, accumulating into an external variable.
Common Mistakes
- Using map() just for side effects and ignoring the return value — wastes memory creating an unused array
- Using forEach() when you need the result — then assigning to an external variable instead of using map()
- Trying to break out of forEach() with return — return only skips the current iteration, not the loop
Interview Questions
When should you use for...of instead of forEach?
When you need early termination (break/continue), when working with async/await (forEach doesn't await properly), or when iterating non-array iterables (Map, Set, generators).
Does map() mutate the original array?
No, map() always returns a new array. However, if the callback mutates elements that are objects/arrays (reference types), those mutations affect the originals since both arrays share the same object references.