map() vs forEach()
map() builds a new array from a function’s results, while forEach() only calls the function for every element and always returns undefined.
Side-by-side comparison
#What it returns
- Array.prototype.map()
- A new array with the function’s results
- Array.prototype.forEach()
undefined
Length of the result
- Array.prototype.map()
- Always the same as the input array
- Array.prototype.forEach()
- No result
Changes the original array
- Array.prototype.map()
- No, unless the function itself does
- Array.prototype.forEach()
- No, unless the function itself does
Chaining
- Array.prototype.map()
- Yes, e.g.
.map().filter().join() - Array.prototype.forEach()
- No, because it returns
undefined
Breaking out partway through
- Array.prototype.map()
- Not possible
- Array.prototype.forEach()
- Not possible,
breakdoesn’t work (usefor...of)
Typical use
- Array.prototype.map()
- Transforming data, rendering lists in React
- Array.prototype.forEach()
- Logging, saving, changes on the page
Example
#const prices = [10, 20, 30]
const doubled = prices.map((price) => price * 2)
const result = prices.forEach((price) => console.log(price))
console.log(doubled)
console.log(result)Definition and usage
#Both methods walk through the array’s elements in order and call the same function for each one with the arguments (element, index, array). What differs is what happens to the result: map() collects the values the function returns into a new array of the same length, while forEach() ignores them and always returns undefined.
So the choice is simple. When you want to transform the data and keep using the result (prices with tax, a list of names, list items in React), use map(). When you only want to perform a side effect for every element (log it to the console, save it, change an element on the page), use forEach().
Performance isn’t a factor here, because in practice both methods run at the same speed. What matters is readability: a map() whose result no one uses suggests a mistake, and a forEach() with push() into a separate array is just a longer version of map().
Syntax
#const result = array.map((element, index, array) => newValue)
array.forEach((element, index, array) => { /* side effect */ })More examples
#const students = [
{ name: 'Emma', points: 120 },
{ name: 'Jack', points: 95 },
{ name: 'Mia', points: 140 }
]
const summary = students
.map((student) => `${student.name}: ${student.points}`)
.join(', ')
console.log(summary)const names = ['emma', 'jack']
const upperWithForEach = []
names.forEach((name) => upperWithForEach.push(name.toUpperCase()))
const upperWithMap = names.map((name) => name.toUpperCase())
console.log(upperWithForEach)
console.log(upperWithMap)The result is the same, but the map() version is shorter and doesn’t need an empty array to start with.
const scores = [40, 75, 90, 20]
for (const score of scores) {
if (score > 80) {
console.log('First score above 80:', score)
break
}
}Good practices
#- If you’re not using the array returned by
map(), switch it toforEach()or afor...ofloop. - Don’t use
forEach()withawait: the loop doesn’t wait for promises. Reach forfor...oforawait Promise.all(array.map(...)). - Looking for a single element or checking a condition?
find(),some(), andevery()finish their work earlier thanforEach().
Related entries
#- Array.prototype.map()Creates a new array with the results of calling a function for every element.
- Array.prototype.forEach()Calls a function for every element of the array.
- for...ofWalks the successive values of an iterable object: an array, a string, a Map, a Set, and others.
- Array.prototype.filter()Creates a new array with the elements for which the function returned true.
Spotted a mistake or missing an example? Write to us.