Comparison

JavaScript map() vs forEach(): Which Array Method to Use

Comparison of JavaScript map() and forEach() covering return values, chainability, performance, and common bugs.

{ "slug": "javascript-map-vs-foreach", "title": "JavaScript map() vs forEach(): Which Array Method to Use", "description": "Learn the key differences between JavaScript map() and forEach(): return values, chainability, performance, and when to use each with real code examples.", "type": "comparison", "toolSlugs": ["javascript-map", "javascript-foreach", "array-methods", "functional-programming"], "keywords": ["javascript map", "javascript forEach", "array methods", "map vs forEach", "functional javascript", "array iteration", "es6 arrays", "chainable methods"], "content": "
\n

JavaScript map() vs forEach(): The Definitive Comparison

\n

Both map() and forEach() iterate over every element in an array, but they exist for fundamentally different reasons. Picking the wrong one produces subtle bugs and unreadable code. Here is the practical difference and when each belongs in your toolkit.

\n\n

The core semantic difference

\n

map() returns a new array of transformed values. It is a pure, functional operation: input array in, brand-new array out, original untouched. Because it returns an array, you can chain it with other array methods.

\n

forEach() returns undefined. It is an imperative loop designed to run side effects, such as logging, mutating external state, or calling a DOM API. Nothing comes back.

\n
const nums = [1, 2, 3];\n\nconst doubled = nums.map(n => n * 2);\n// doubled = [2, 4, 6]\n\nconst nothing = nums.forEach(n => n * 2);\n// nothing = undefined  (the result is thrown away)
\n\n

When to use map()

\n

Reach for map() whenever you want to transform each element into a new value and collect the results. Rendering lists in React, converting API responses, and reshaping data are canonical use cases.

\n
const users = [\n  { id: 1, first: 'Ada', last: 'Lovelace' },\n  { id: 2, first: 'Grace', last: 'Hopper' }\n];\n\nconst displayNames = users.map(u => `${u.first} ${u.last}`);\n// ['Ada Lovelace', 'Grace Hopper']
\n\n

When to use forEach()

\n

Use forEach() when you need side effects and do not care about a return value: writing to a database, logging, dispatching events, or updating a DOM node in place.

\n
const buttons = document.querySelectorAll('.btn');\n\nbuttons.forEach(btn => {\n  btn.addEventListener('click', handleClick);\n});\n\n// Logging is another honest forEach use case\nusers.forEach(u => console.log(u.id, u.first));
\n\n

Chainability: map()'s superpower

\n

Because map() returns an array, it composes cleanly with filter(), reduce(), and other array methods. This is where functional pipelines shine.

\n
const orders = [\n  { item: 'book', price: 12, inStock: true  },\n  { item: 'pen',  price: 3,  inStock: false },\n  { item: 'lamp', price: 40, inStock: true  }\n];\n\nconst total = orders\n  .filter(o => o.inStock)         // keep in-stock items\n  .map(o => o.price * 1.08)       // add 8% tax\n  .reduce((sum, p) => sum + p, 0); // sum them\n\n// total = 56.16
\n

You cannot express this pipeline with forEach() without introducing a mutable accumulator variable, which defeats the point.

\n\n

Performance

\n

For small-to-medium arrays, the difference is negligible; both are optimized in modern engines. In tight, hot-path loops over hundreds of thousands of elements, a plain for loop or for...of can be modestly faster than either because it avoids the per-iteration callback invocation. That said, this rarely matters in application code, and readability should almost always win. Measure before you optimize.

\n
// Only reach for this style when profiling proves you need it\nlet sum = 0;\nfor (let i = 0; i < nums.length; i++) sum += nums[i];
\n\n

Common bugs

\n

Forgetting to return from a map callback. An arrow function with braces needs an explicit return, or every element becomes undefined.

\n
// Bug: no return -> [undefined, undefined, undefined]\nconst broken = nums.map(n => { n * 2; });\n\n// Fix: return explicitly, or drop the braces\nconst fixed1 = nums.map(n => { return n * 2; });\nconst fixed2 = nums.map(n => n * 2);
\n

Using forEach() when you meant map(). Pushing into an outer array from inside forEach() is a code smell that map handles for free.

\n
// Anti-pattern\nconst result = [];\nnums.forEach(n => result.push(n * 2));\n\n// Idiomatic\nconst result = nums.map(n => n * 2);
\n

Using map() purely for side effects. If you discard the returned array, you are allocating memory for nothing. Use forEach() instead.

\n\n

Quick decision guide

\n
    \n
  • Need a transformed array? map()
  • \n
  • Chaining with filter/reduce? map()
  • \n
  • Running side effects, no return value needed? forEach()
  • \n
  • Need to break out of the loop early? Neither, use for...of with break, or some()/every()
  • \n
\n

Choose based on intent, not habit. Your future readers, including you, will thank you.

\n
" }
javascript map javascript forEach array methods map vs forEach functional javascript array iteration es6

Explore 300+ Free Tools

Utilko has tools for developers, writers, designers, students, and everyday users — all free, all browser-based.