Back to blog

How to Loop Through an Array in JavaScript: Iterators Compared

Iterating over arrays is one of the most fundamental operations in JavaScript programming. As the language evolved, multiple ways to loop through arrays were introduced.

Today, developers can choose between traditional index loops, modern declarations like for...of, or functional prototypes like forEach() and map().

Selecting the wrong iterator can lead to bugs, especially when handling asynchronous tasks or attempting to interrupt execution.

In this guide, we will compare the four main array iteration methods, analyze how they handle asynchronous await processes, and review interruption support.

1. The Traditional for Loop

The classical for loop is the oldest and most performant way to loop over arrays.

const items = ['A', 'B', 'C'];

for (let i = 0; i < items.length; i++) {
  console.log(`Index ${i}: ${items[i]}`);
}

Pros and Cons

  • Pros: Highly optimized by browser JS engines. Offers complete control over indices.
  • Cons: Verbose syntax prone to off-by-one errors.
  • Control Flow: Fully supports break to exit early, continue to skip the current item, and return inside functions.

2. The ES6 for...of Loop

Introduced in ES6, the for...of loop provides a clean, readable syntax to iterate over iterable objects (including arrays, sets, and maps) without managing indices manually.

const fruits = ['Apple', 'Banana', 'Orange'];

for (const fruit of fruits) {
  console.log(fruit);
}

Pros and Cons

  • Pros: Clean, readable, and less error-prone.
  • Control Flow: Fully supports break, continue, and return.
  • Async Support: Best choice for asynchronous loops. It suspends execution sequentially when using await:
// Sequentially resolves promises one by one
for (const url of urls) {
  const data = await fetchPage(url);
  console.log(data);
}

3. The Array.prototype.forEach Method

Functional style iteration is clean. The forEach() method executes a callback function for each array element.

const colors = ['Red', 'Green', 'Blue'];

colors.forEach((color, index) => {
  console.log(`${index}: ${color}`);
});

Pros and Cons

  • Pros: Declarative and preserves scope variables inside the callback closure.
  • Cons: No break/continue support. If you write break inside a forEach callback, the compiler throws a SyntaxError. Writing return inside forEach does not exit the loop; it acts like a continue statement, skipping to the next iteration.
  • Async Limitation: forEach is not promise-aware. If you use await inside the callback, the loop executes all iterations concurrently rather than waiting for each promise to resolve.

4. The Array.prototype.map Method

The map() method is designed for data transformation. It executes a callback on each element and returns a new array containing the results.

const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);

console.log(doubled); // Outputs: [2, 4, 6]

Pros and Cons

  • Pros: Perfect for functional programming. Does not mutate the original array.
  • Cons: Never use map to perform side-effects (like writing logs or saving data to databases) where you do not use the returned array. That is an anti-pattern that creates unnecessary memory allocation overhead.

Loop Method Comparison Matrix

Feature for for...of forEach() map()
Syntax Style Imperative Imperative Declarative Functional
Supports break / continue? Yes Yes No No
Supports sequential await? Yes Yes No No
Returns a new array? No No No Yes
Performance Highest High Medium Medium

Conclusion

Selecting the correct array iteration method depends on your application's logic. Default to the modern for...of loop for general iteration and asynchronous operations requiring sequential execution. Utilize forEach() for simple, uninterrupted side-effect loops, employ map() when you need to transform one array structure into another, and reserve the traditional for loop for performance-critical hot paths.