JavaScript for Each Item in Array: Practical Guide

Learn how to use for each item in array in JavaScript, including syntax, callback parameters, side effects, and when to choose forEach over map or reduce. Practical examples, common pitfalls, and performance tips for developers.

JavaScripting
JavaScripting Team
·5 min read
Iterating Arrays - JavaScripting
Quick AnswerDefinition

JavaScript for each item in array uses Array.prototype.forEach to run a callback for every element. It processes items in order, but does not produce a new array or return a value. The callback receives currentValue, index, and the original array, and is ideal for side effects rather than transformations.

What 'javascript for each item in array' means

According to JavaScripting, the phrase describes using Array.prototype.forEach to execute a callback for every element in an array. This is the most direct way to perform side effects as you walk through a collection, such as logging values or mutating external state. In contrast to map or reduce, forEach does not return a transformed array; it simply applies the callback to each element. Here is a basic example to illustrate the idea:

JavaScript
const nums = [1, 2, 3]; nums.forEach(n => console.log(n));

Key takeaways:

  • The callback receives (currentValue, index, array)
  • forEach runs synchronously and in order
  • Avoid using forEach if you need a new array from the results

Callback signature and parameters

The forEach method calls the provided function once for each array element, supplying three arguments: currentValue, index, and the original array. This makes it easy to access the element and its position during iteration. You can also use the third parameter if you need to reference the entire array inside the callback:

JavaScript
const letters = ['a','b','c']; letters.forEach((value, idx, arr) => { console.log(`value=${value}, index=${idx}, length=${arr.length}`); });

Note:

  • Returning a value from the callback has no effect on forEach’s overall result
  • Use the index for position-based logic or to sync with another array

Side effects vs transformations

One common decision when iterating with forEach is whether you intend to produce a side effect (like logging or mutating outside state) or transform data into a new structure. forEach is perfect for side effects but not for creating a transformed array. If you need a new array, prefer map or reduce:

JavaScript
const nums = [1, 2, 3]; const doubled = nums.map(n => n * 2); console.log(doubled); // [2, 4, 6]

Conversely, if you still must perform a side effect inside the loop:

JavaScript
const objs = [{v:1},{v:2}]; const totals = []; objs.forEach(o => totals.push(o.v)); console.log(totals); // [1, 2]

Bottom line: use forEach for actions with side effects; use map/reduce when you need a new array based on transformed data

Alternatives: map, filter, reduce

JavaScript provides several imperative patterns that can make code clearer depending on the goal. map creates a new array by transforming each element, filter selects elements, and reduce aggregates results. Here are concise examples:

JavaScript
const nums = [1,2,3,4]; // map: create a new array with each element doubled const doubled = nums.map(n => n * 2); console.log(doubled); // [2,4,6,8] // filter: keep only even numbers const evens = nums.filter(n => n % 2 === 0); console.log(evens); // [2,4] // reduce: compute the sum of all numbers const sum = nums.reduce((acc, cur) => acc + cur, 0); console.log(sum); // 10

When you need a simple iteration with side effects, forEach is concise; for data transformation, map (and occasionally reduce) becomes the better choice

Async patterns and forEach caveats

Using forEach with asynchronous work inside the callback often leads to surprising results because forEach does not await promises. This can leave operations unfinished. Consider these patterns:

JavaScript
const urls = ['https://api.example.com/1','https://api.example.com/2']; urls.forEach(async url => { const res = await fetch(url); console.log(await res.json()); });

The above starts all fetches, but you won’t be able to await completion. A safer approach is to use Promise.all with map:

JavaScript
const results = await Promise.all(urls.map(url => fetch(url).then(r => r.json()))); console.log(results);

If you need sequential processing, use a for...of loop with await:

JavaScript
async function fetchSequential(urls){ const results = []; for (const url of urls){ const r = await fetch(url); results.push(await r.json()); } return results; }

Summary: forEach can run async work, but you should use Promise.all with map or a for...of loop when you need reliable sequencing or final results.

Real-world example: processing data

Consider a practical scenario where you need to enrich a list of users with a computed badge based on activity. You can log results or mutate each user object as needed, but avoid returning a new array from forEach. Here’s a realistic approach:

JavaScript
const users = [ { id: 1, name: 'Ada', activity: 92 }, { id: 2, name: 'Linus', activity: 55 }, { id: 3, name: 'Grace', activity: 78 } ]; users.forEach(u => { if (u.activity > 80) u.badge = 'Gold'; else if (u.activity > 60) u.badge = 'Silver'; else u.badge = 'Bronze'; }); console.log(users);

This pattern is common in data normalization pipelines or when wiring up data for UI rendering in frameworks. If you need a derived array, switch to map:

JavaScript
const names = users.map(u => u.name);

By understanding the distinction, you keep your code intention clear and avoid accidental data duplication.

Debugging and common errors

Debugging forEach loops often reveals logical mistakes around side effects. Common errors include assuming forEach returns a value, mutating the same array while iterating, or relying on asynchronous work inside the loop without proper awaiting. Tips:

JavaScript
// Wrong: thinking forEach returns a new array const result = [1,2,3].forEach(n => n * 2); console.log(result); // undefined // Correct: use map for transformations const transformed = [1,2,3].map(n => n * 2); console.log(transformed); // [2,4,6]

When debugging, log the loop state inside the callback and consider breaking the loop with a separate flag or using a for...of loop if you need early termination.

Additionally, ensure you are not mutating the array while iterating in a way that affects the loop condition or length unintentionally.

Best practices and when to use forEach

In summary, choose forEach when you need to perform side effects in a predictable, sequential pass. Reserve map for transforming data into a new array, reduce for aggregation, and for...of for cases requiring early exits or awaiting asynchronous work. Align your choice with the data flow you want to express, and favor readability over cleverness. Remember: the goal is clear intent and maintainable code; forEach is a tool, not a universal replacement.

Steps

Estimated time: 40-60 minutes

  1. 1

    Set up your array

    Create an array of values you will iterate with forEach. Decide whether you will mutate external state or compute a derived result.

    Tip: Keep data immutable where possible to simplify debugging.
  2. 2

    Choose the operation

    If you only need side effects, plan your callback accordingly. If you need a transformed array, consider map.

    Tip: Ask: Do I need a new array or just perform an action?
  3. 3

    Write the forEach loop

    Implement the callback with the required parameters (value, index, array). Include comments to explain intent.

    Tip: Use meaningful variable names inside the callback.
  4. 4

    Test with simple data

    Run the code with small examples to verify output matches expectations.

    Tip: Add console.log statements to trace values.
  5. 5

    Handle side effects safely

    If you mutate external state, ensure there are no race conditions or unintended side effects.

    Tip: Document any side effects in code comments.
  6. 6

    Compare with map/reduce

    If a transformation is needed, rewrite using map or reduce for correctness and readability.

    Tip: Prefer clear, explicit data flow over cleverness.
  7. 7

    Consider async needs

    If your operation involves asynchronous work, decide between Promise.all/map or a for...of loop with await.

    Tip: Avoid mixing forEach with unawaited promises.
  8. 8

    Finalize and profile

    Run performance checks if the loop is critical to a hot path; optimize only if necessary.

    Tip: Premature optimization can hurt readability.
Pro Tip: Use forEach when you need side effects; use map for transformations.
Warning: Do not rely on forEach to handle asynchronous work; prefer Promise.all with map or a for...of loop with await.
Note: Remember that forEach does not return a value; assignments should be outside the callback when building results.

Prerequisites

Required

Optional

Commands

ActionCommand
Run a JavaScript file with NodeFrom project root
Install npm dependenciesIn project folder
Run a one-linerQuick test in terminal

Questions & Answers

What is the difference between forEach and map?

forEach iterates over an array to perform side effects and returns undefined. map creates a new array by applying a transformation to each element. Use map when you need a new array and forEach when you only need to run code for each item.

forEach runs a function for every element but doesn’t produce a new array; map does. Use them for different purposes to keep code clear.

Can I break out of a forEach loop?

No. forEach does not support breaking early. If you need to stop, use a traditional for loop or a for...of loop with a break statement.

You can’t break out of forEach; switch to a for loop if you need early exit.

What about async work inside forEach?

ForEach does not wait for asynchronous operations. If you need to await, use Promise.all with map or a for...of loop with await.

Don’t rely on forEach for async tasks; use Promise.all or a for...of loop instead.

Is forEach faster than a standard for loop?

Performance is usually similar; micro-optimizations are rarely worth sacrificing readability. Use the construct that best communicates intent.

Performance differences are minor; readability matters more in most cases.

Can I mutate the original array inside forEach?

Yes, you can modify elements within the loop. Be mindful of side effects and ensure this is intentional.

You can change items inside the loop, but be careful with state changes.

When should I use forEach in real projects?

Use forEach for clean, straightforward side effects like logging, counters, or incremental mutations. For data transformation, prefer map or reduce.

Use it when you just need to act on each item, not build a new array.

What to Remember

  • Master forEach for side effects only
  • Callback signature includes value, index, array
  • forEach does not return a transformed array
  • Use map/reduce for data transformation
  • Prefer for...of with await for async operations

Related Articles