DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. forEach vs map in JavaScript: When to Use Which
XLinkedInReddit
MediumFrontend Engineering

forEach vs map in JavaScript: When to Use Which

D
DevPrep Team
February 9, 2026·2 min read·0
Table of Contents
  • The One Rule
  • Core Difference
  • Common Mistakes
  • Mistake 1: Using map When You Do Not Need the Result
  • Mistake 2: Using forEach to Build an Array
  • Mistake 3: Trying to Break Out of forEach
  • Performance
  • Async Gotcha
  • Best Practices
  • Summary

By Rahul — Google Frontend Engineer

The One Rule

If you need the result array, use map(). If you do not, use forEach(). That is it. But let me show you why people get this wrong and what happens in production.

Core Difference

const numbers = [1, 2, 3, 4, 5];

// map returns a NEW array
const doubled = numbers.map(n => n * 2);
// doubled = [2, 4, 6, 8, 10]

// forEach returns undefined
const result = numbers.forEach(n => console.log(n));
// result = undefined

Common Mistakes

Mistake 1: Using map When You Do Not Need the Result

// BAD — creates an array and throws it away
users.map(user => {
  sendEmail(user.email);
});

// GOOD
users.forEach(user => {
  sendEmail(user.email);
});

ESLint rule array-callback-return catches this. Enable it.

Mistake 2: Using forEach to Build an Array

// BAD — manual push
const names = [];
users.forEach(user => {
  names.push(user.name);
});

// GOOD — map does this naturally
const names = users.map(user => user.name);

Mistake 3: Trying to Break Out of forEach

// This does NOT work
[1, 2, 3, 4, 5].forEach(n => {
  if (n === 3) return; // Only skips this iteration
  // break; — SyntaxError!
  console.log(n);
});
// Logs: 1, 2, 4, 5

// Use for...of if you need to break
for (const n of [1, 2, 3, 4, 5]) {
  if (n === 3) break;
  console.log(n);
}
// Logs: 1, 2

Performance

In V8, for loop is fastest, forEach and map have similar overhead. For arrays under 10,000 items, the difference is negligible. For very large datasets, consider for loops or streaming approaches.

Async Gotcha

// BAD — fires all requests simultaneously, does not await
urls.forEach(async (url) => {
  await fetch(url); // This does NOT wait
});

// GOOD — sequential
for (const url of urls) {
  await fetch(url);
}

// GOOD — parallel
await Promise.all(urls.map(url => fetch(url)));

This is one of the most common production bugs. forEach does not respect async/await. The callback fires and forEach moves on immediately.

Best Practices

  • Use map for transformations (data in → data out)
  • Use forEach for side effects (logging, API calls, DOM mutations)
  • Never use forEach with async callbacks — use for...of or Promise.all with map
  • Enable array-callback-return ESLint rule

Summary

map transforms. forEach performs side effects. The async gotcha alone makes this worth understanding deeply.

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • The One Rule
  • Core Difference
  • Common Mistakes
  • Mistake 1: Using map When You Do Not Need the Result
  • Mistake 2: Using forEach to Build an Array
  • Mistake 3: Trying to Break Out of forEach
  • Performance
  • Async Gotcha
  • Best Practices
  • Summary

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.