Five ways to loop, each with a personality. The decision rules:
The lineup
for (let i = 0; i < arr.length; i++) // need the index / break early / max speed for (const item of arr) // clean iteration, break works โ DEFAULT for (const key in obj) // objects only (includes inherited keys!) arr.forEach((item, i) => ...) // callback style; no break; skips holes const out = arr.map(x => x * 2) // TRANSFORM โ returns a new array
The rules
- Producing a new array from each element? map. Just doing side effects? for...of or forEach
- Need to
break/continue/return? for or for...of โ forEach cannot break (throwing to escape is a smell) - Objects:
Object.entries(obj)+ for...of beats for...in (no prototype surprises)
The async trap (interview classic)
// โ forEach ignores await โ all fire at once, loop "finishes" instantly items.forEach(async (x) => await save(x)); // โ sequential for (const x of items) await save(x); // โ parallel, properly awaited await Promise.all(items.map(x => save(x)));
Full lesson: Loops.