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
mapis like a photocopier with a filter: you get a new stack of pages, original untouchedforEachis a highlighter: it marks things in place and gives you nothing back- Main difference:
mapreturns a new array,forEachreturnsundefined - Need a new array? Use
map. Just logging or updating something external? UseforEach forEachcannot be chained;mapchains with.filter(),.reduce(), etc.
Quick example
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); // undefinedBoth 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;forEachreturnsundefinedand breaks render)
Comparison table
| Aspect | map | forEach |
|---|---|---|
| Returns | New array | undefined |
| Original array | Unchanged | Unchanged (unless callback mutates) |
| Chainable | Yes | No |
| Use for | Transformations | Side effects |
| Performance | Slightly 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:
const doubled = [1, 2, 3].forEach(n => n * 2);
console.log(doubled); // undefined, not [2, 4, 6]Fix: use map.
Chaining after forEach:
[1, 2, 3].forEach(x => x * 2).filter(x => x > 2);
// TypeError: Cannot read properties of undefinedFix: use map first, then chain.
Mutating the original inside map:
const arr = [1, 2, 3];
arr.map((n, i) => { arr[i] = n * 2; }); // mutates arr directlymap 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:
users.map(user => console.log(user.name)); // allocates array nobody usesFix: 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.
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 untouchedmap 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
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 readyA concise answer to help you respond confidently on this topic during an interview.