FSIBLOG

JavaScript Loop Through Array: 7 Ways Tested With Output

Paste this into your browser console and guess the order of the output before you look.

const wait = (ms) => new Promise(r => setTimeout(r, ms));
const ids = [1, 2, 3];
const log = [];

ids.forEach(async (id) => {
  await wait(10);
  log.push('saved ' + id);
});
log.push('done');

setTimeout(() => console.log(log), 50);

Output

[ 'done', 'saved 1', 'saved 2', 'saved 3' ]

“done” comes first, even though it is the last line of the code. forEach does not wait for await. It starts all three saves and moves straight on. Swap in for...of and the order comes out right:

for (const id of ids) {
  await wait(10);
  log.push('saved ' + id);
}
log.push('done');

Output

[ 'saved 1', 'saved 2', 'saved 3', 'done' ]

Every loop below looks like it does the same job. They don’t. This guide shows each one with code and real output, a tested table of what each can and can’t do, and a speed test on one million items.

Which Loop to Use: The Short Answer

The Array Used in Every Example

All the examples below use this small shopping cart, so you can compare outputs line for line.

const cart = [
  { name: 'Mouse', price: 25, qty: 2 },
  { name: 'Keyboard', price: 60, qty: 1 },
  { name: 'Cable', price: 8, qty: 3 },
];

Seven Ways to Loop Through an Array, With Output

1. for…of: The Default for Most Loops

let total = 0;
for (const item of cart) {
  total += item.price * item.qty;
}
console.log(total);

Output

134
for (const item of cart) {
  if (item.price > 50) {
    console.log('Found:', item.name);
    break;
  }
}

Output

Found: Keyboard

2. for…of With entries(): When You Need the Index

for (const [i, item] of cart.entries()) {
  console.log(`${{i + 1}}. ${{item.name}}`);
}

Output

1. Mouse
2. Keyboard
3. Cable

3. The Classic for Loop: Full Control and the Fastest

for (let i = 0; i < cart.length; i++) {
  console.log(i + 1, cart[i].name);
}

Output

1 Mouse
2 Keyboard
3 Cable

4. forEach(): Fine for Simple Side Effects

cart.forEach((item, i) => {
  console.log(i, item.name, item.price);
});

Output

0 Mouse 25
1 Keyboard 60
2 Cable 8

5. map() and filter(): When You Want a New Array

const names = cart.map(item => item.name);
const cheap = cart.filter(item => item.price < 30);

console.log(names);
console.log(cheap.map(item => item.name));

Output

[ 'Mouse', 'Keyboard', 'Cable' ]
[ 'Mouse', 'Cable' ]

6. reduce(): When You Want One Value Back

const sum = cart.reduce((acc, item) => acc + item.price * item.qty, 0);
console.log(sum);

Output

134

7. while: When You Don’t Know How Many Rounds You Need

const queue = [...cart];

while (queue.length > 0) {
  const item = queue.shift();
  console.log('Packing', item.name);
}

Output

Packing Mouse
Packing Keyboard
Packing Cable

Shortcuts That Stop Early: find() and some()

const firstBig = cart.find(item => item.price > 50);
const hasBulk = cart.some(item => item.qty >= 3);

console.log(firstBig);
console.log(hasBulk);

Output

{{ name: 'Keyboard', price: 60, qty: 1 }}
true

What Each Loop Can and Can’t Do

We ran each behaviour in Node.js 22. Ticks are what actually happened, not what the loop is meant to do.

Loopbreakawait in orderGives indexReturns new arrayEmpty slots
for...ofYesYesWith entries()NoVisits them
forYesYesYesNoVisits them
whileYesYesYou manage itNoVisits them
forEach()SyntaxErrorNoYesNoSkips them
map()NoNoYesYesSkips them
reduce()NoNoYesOne valueSkips them
for...inYesYesAs a stringNoSkips them

“Empty slots” means a gap such as [1, , 3]. In our test, forEach gave [1, 3] while for...of gave [1, undefined, 3].

How Fast Each Loop Is on One Million Numbers

Four Mistakes That Give Wrong Results

Using await Inside forEach

const results = await Promise.all(cart.map(item => save(item)));

Output

[ 'Mouse', 'Keyboard', 'Cable' ]

Trying to break Out of forEach

Using for…in on an Array

const arr = ['a', 'b'];
arr.extra = 'x';

for (const key in arr) console.log(key, typeof key);

Output

0 string
1 string
extra string

Forgetting Return in Map()

[1, 2, 3].map(x => { x * 2; });

Output

[ undefined, undefined, undefined ]

Exit mobile version