JS Array map vs forEach: Which Should You Use?

map() returns a new array. forEach() returns undefined. Learn the key differences, when to use each, and why choosing the right one makes your code cleaner.

6 min read

map() and forEach() both iterate over every element of an array and run a function on each one. The syntax looks almost identical, and beginners often use them interchangeably. But they serve fundamentally different purposes.

Here is the difference in one sentence: map() returns a new array with transformed values. forEach() returns undefined and only runs side effects.

map()forEach()
ReturnsA new arrayundefined
PurposeTransform dataRun side effects
ChainableYes (.map().filter())No
Mutates original?NoNot by itself
Use caseConvert, extract, computeLog, save, update DOM

map() -- Transform and Return

map() calls a function on every element and collects the return values into a new array. The original array is not changed.

javascriptjavascript
const prices = [10, 20, 30];
 
const withTax = prices.map(price => price * 1.1);
 
console.log(withTax); // [11, 22, 33]
console.log(prices);  // [10, 20, 30] (unchanged)

Each element goes through the transformation function. The result is a new array where every element corresponds to the original, transformed.

map() is ideal when you need to:

  • Convert an array of numbers (prices to withTax)
  • Extract a property from an array of objects
  • Format data for display
  • Apply a computation to every element

Extracting Properties with map()

javascriptjavascript
const users = [
  { id: 1, name: "Alice", city: "New York" },
  { id: 2, name: "Bob", city: "London" },
  { id: 3, name: "Carol", city: "Tokyo" }
];
 
const names = users.map(user => user.name);
console.log(names); // ["Alice", "Bob", "Carol"]

Chaining map() with Other Methods

Because map() returns an array, you can chain it with filter(), reduce(), sort(), and other array methods:

javascriptjavascript
const numbers = [1, 2, 3, 4, 5, 6];
 
const doubledEvens = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * 2);
 
console.log(doubledEvens); // [4, 8, 12]

This is one of map()'s biggest advantages. You cannot do this with forEach() because it returns undefined.

forEach() -- Run Side Effects

forEach() calls a function on every element but ignores the return value. It always returns undefined. Use it when you need to do something, not produce something.

javascriptjavascript
const items = ["apple", "banana", "cherry"];
 
items.forEach(item => {
  console.log(`Found: ${item}`);
});
// Found: apple
// Found: banana
// Found: cherry

The callback runs three times, but nothing is collected. forEach() is about the journey, not the destination.

forEach() is the right choice when you need to:

  • Log values for debugging
  • Save each item to a database or API
  • Update the DOM for each element
  • Push into an external array

Building an Array with forEach() (Push Pattern)

If you use forEach() to build an array by pushing, you are probably using the wrong method:

javascriptjavascript
const numbers = [1, 2, 3];
const doubled = [];
 
// Works, but map() is cleaner
numbers.forEach(n => {
  doubled.push(n * 2);
});
 
console.log(doubled); // [2, 4, 6]

This is a map() operation written with forEach(). It works but is more code, mutates an external array, and cannot be chained. The equivalent with map() is one line:

javascriptjavascript
const doubled = numbers.map(n => n * 2);

Side-by-Side Behavior

Calling both methods with the identical callback on the same array makes the difference in return values obvious. map() hands back a new array, while forEach() hands back nothing at all:

javascriptjavascript
const nums = [1, 2, 3];
 
const mapped = nums.map(n => n * 10);
console.log(mapped); // [10, 20, 30]
 
const eachResult = nums.forEach(n => n * 10);
console.log(eachResult); // undefined

Even though the forEach() callback computes n * 10, the result is discarded. forEach() does not care what your callback returns.

When to Use Each

Use map():

  • When you want to transform every element and get a new array.
  • When you plan to chain more array methods.
  • When working with React or other frameworks that expect new arrays for rendering.

Use forEach():

  • When you need to run a side effect for each element (logging, saving, DOM updates).
  • When you do not need a return value.
  • When you are iterating over an existing array to call an external function on each item.

The choice usually comes down to what you plan to do with the result, as this side-by-side use of both methods on the same array shows:

javascriptjavascript
const users = [{ id: 1 }, { id: 2 }];
 
const ids = users.map(u => u.id);
console.log(ids); // [1, 2]
 
users.forEach(u => console.log(`Saving user ${u.id}`));

Common Mistakes

Using map() for side effects and ignoring the return value. Calling map() just to log each item still builds and discards an entire array in the process:

javascriptjavascript
const items = ["a", "b", "c"];
 
items.map(item => console.log(item));

forEach() does the same logging without creating that wasted array, since it never expects the callback to return anything useful in the first place:

javascriptjavascript
const items = ["a", "b", "c"];
 
items.forEach(item => console.log(item));

Using map() for side effects creates an unused array and misleads readers into thinking a transformation is happening.

Using forEach() when you need a new array. Manually building a result array with forEach() and push() works, but it takes more code than map() and mutates an array outside the callback:

javascriptjavascript
const users = [{ name: "Alice" }, { name: "Bob" }];
 
const names = [];
users.forEach(u => names.push(u.name));
 
console.log(names); // ["Alice", "Bob"]

map() does the same thing in one line, with no separate array to declare or push into, since the returned array becomes names directly:

javascriptjavascript
const users = [{ name: "Alice" }, { name: "Bob" }];
 
const names = users.map(u => u.name);
 
console.log(names); // ["Alice", "Bob"]

Trying to chain after forEach(). Since forEach() always returns undefined, calling another array method directly on its result throws an error instead of continuing the chain:

javascriptjavascript
const nums = [1, 2, 3];
 
// Error: forEach returns undefined, cannot call filter on undefined
nums.forEach(n => n * 2).filter(n => n > 2); // TypeError

Now that you understand map() and forEach(), learn about other array methods that return boolean results with some and every, or the powerful filter method for selecting elements.

Rune AI

Rune AI

Key Insights

  • map() returns a new array with the results of calling a function on every element.
  • forEach() returns undefined. It only runs side effects.
  • Use map() for transforming data: converting, extracting, or computing new values.
  • Use forEach() for side effects: logging, saving to a database, updating the DOM.
  • map() enables method chaining. forEach() does not.
RunePowered by Rune AI

Frequently Asked Questions

Can I chain methods after forEach()?

No. forEach() returns undefined, so you cannot chain. map() returns a new array, which lets you chain filter(), reduce(), sort(), and other array methods.

Does map() mutate the original array?

No. map() always returns a new array and leaves the original untouched. However, if your callback mutates the original objects inside the array, those changes will be visible in both.

Is map() slower than forEach()?

map() creates a new array, so it uses more memory than forEach(). But the performance difference is negligible for arrays under thousands of elements. Choose based on intent, not micro-optimization.

Conclusion

map() and forEach() look similar but serve different purposes. Use map() when you want to transform data and get a new array. Use forEach() when you need to run side effects and do not care about a return value. Choosing the right one makes your intent clear: map() says 'I am building something new,' while forEach() says 'I am doing something.'