Skip to main content

What is the difference between Map and foreach in Array?

map returns a new array with transformed values; forEach runs a function on each element and returns undefined.

Theory

TL;DR

  • map is like a photocopier with a filter: you get a new stack of pages, original untouched
  • forEach is a highlighter: it marks things in place and gives you nothing back
  • Main difference: map returns a new array, forEach returns undefined
  • Need a new array? Use map. Just logging or updating something external? Use forEach
  • forEach cannot be chained; map chains with .filter(), .reduce(), etc.

Quick example

javascript
const nums = [1, 2, 3]; // map returns a new array const doubled = nums.map(n => n * 2); console.log(doubled); // [2, 4, 6] console.log(nums); // [1, 2, 3] - unchanged // forEach returns undefined const result = nums.forEach(n => n * 2); console.log(result); // undefined

Both methods visit every element. map collects the callback's return values into a new array. forEach ignores them.

Key difference

map builds and returns a new array of the same length, where each slot holds whatever the callback returned. The original array stays intact. forEach runs the callback purely for side effects, discards the return value, and gives back undefined. That single difference decides which one to pick. Mixing them up is one of the most common trip-ups I see in code reviews.

When to use

  • Transform data for display (format names, convert units, reshape objects) → map
  • Log or debug array contents → forEach
  • Build a method chain like .map().filter().reduce()map
  • Push items into an external array or trigger API calls in a loop → forEach
  • Render JSX lists in React → map (returns array; forEach returns undefined and breaks render)

Comparison table

AspectmapforEach
ReturnsNew arrayundefined
Original arrayUnchangedUnchanged (unless callback mutates)
ChainableYesNo
Use forTransformationsSide effects
PerformanceSlightly slower (allocates new array)Slightly faster (no allocation)

How it works internally

Both methods iterate over the array length and invoke the callback with (value, index, array). The difference is what happens to that return value. map pre-allocates a new array of the same length and stores each result at the matching index. forEach discards every return value and exits with undefined.

Common mistakes

Expecting forEach to return an array:

javascript
const doubled = [1, 2, 3].forEach(n => n * 2); console.log(doubled); // undefined, not [2, 4, 6]

Fix: use map.

Chaining after forEach:

javascript
[1, 2, 3].forEach(x => x * 2).filter(x => x > 2); // TypeError: Cannot read properties of undefined

Fix: use map first, then chain.

Mutating the original inside map:

javascript
const arr = [1, 2, 3]; arr.map((n, i) => { arr[i] = n * 2; }); // mutates arr directly

map does not prevent mutation. If you are mutating inside it, you are using the wrong tool. map is for returning new values, not for changing the original in place.

Using map only for side effects:

javascript
users.map(user => console.log(user.name)); // allocates array nobody uses

Fix: users.forEach(user => console.log(user.name)).

Real-world usage

  • React: users.map(user => <UserCard key={user.id} user={user} />) - render lists
  • Redux: state.items.map(item => ({ ...item, isNew: true })) - immutable state updates
  • Express: req.body.users.map(user => user.id) - extract IDs before a DB query
  • Node.js: data.forEach(chunk => stream.write(chunk)) - write data without collecting results

Follow-up questions

Q: What does forEach return?
A: Always undefined. The callback's return value is discarded completely.

Q: Can you mutate the original array inside map?
A: Yes, but you should not. map is for producing new values. If you need in-place mutation, use a plain for loop.

Q: When is forEach faster than map?
A: Always slightly, because it skips allocating a new array. The gap only matters with very large arrays.

Q: Why does map work in a React component render but forEach does not?
A: React expects an array of JSX elements. map returns that array. forEach returns undefined, which React cannot render.

Q: Implement map using forEach.
A: const myMap = (arr, fn) => { const result = []; arr.forEach((item, i) => { result[i] = fn(item, i, arr); }); return result; };

Examples

Transforming API response data

A typical pattern: you get raw objects from an API and need a different shape before passing them to a component.

javascript
const users = [ { id: 1, firstName: 'Anna', lastName: 'Smith' }, { id: 2, firstName: 'Bob', lastName: 'Jones' }, ]; // map builds a new array with the shape the component actually needs const displayNames = users.map(user => ({ id: user.id, fullName: `${user.firstName} ${user.lastName}`, })); console.log(displayNames); // [{ id: 1, fullName: 'Anna Smith' }, { id: 2, fullName: 'Bob Jones' }] console.log(users); // original untouched

map is the right call here because we need a new array for the component. Using forEach would force us to declare an external array and push manually: more code, same result.

Side effects with forEach

javascript
const orders = [ { id: 101, total: 49.99, status: 'pending' }, { id: 102, total: 120.0, status: 'shipped' }, ]; // forEach: log each order, no new array needed orders.forEach(order => { console.log(`Order #${order.id}: $${order.total} (${order.status})`); }); // Trigger a conditional side effect per item orders.forEach(order => { if (order.status === 'pending') { sendReminderEmail(order.id); } });

No return value is needed here. map would technically work but would allocate an array of undefined values that no one uses.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?