JavaScript has more loop styles than most languages. The good news: for modern code you mostly need two — for...of for items and the classic for for counting.
for (const item of array) visits values — the modern default. Classic for (let i = 0; i < n; i++) when you need the index or step control. while (condition) repeats until false. break exits; continue skips ahead.
const names = ["ada", "alan", "grace"];
for (const name of names) {
console.log(name.toUpperCase());
}
for (const ch of "hi") console.log(ch); // works on strings too
// need the index as well?
for (const [i, name] of names.entries()) {
console.log(`${i + 1}. ${name}`);
}for (let i = 10; i > 0; i--) {
console.log(i); // countdown — full control
}
let tries = 0;
while (tries < 3) {
console.log("attempt", ++tries);
}
do {
// runs AT LEAST once, then checks
} while (false);for (const n of [4, 9, 16, 25, 36]) {
if (n > 20) break; // stop the whole loop
if (n % 2 !== 0) continue; // skip odds
console.log(n); // 4 16
}const nums = [1, 2, 3];
nums.forEach((n, i) => console.log(i, n)); // fine for simple cases
// BUT: no break/continue, and await doesn't pause it:
// nums.forEach(async n => await save(n)); // fires all at once!
for (const n of nums) {
await save(n); // ✓ awaits one at a time
}const scores = { ada: 95, alan: 88 };
for (const key in scores) {
console.log(key, scores[key]);
}
// cleaner modern version:
for (const [name, score] of Object.entries(scores)) {
console.log(name, score);
}
// never use for...in on ARRAYS — keys come back as stringsfor...of gives values of an iterable (arrays, strings); for...in gives property KEYS of an object. Arrays want for...of.
No — forEach can't break or continue. Use for...of, or .some()/.every() when a short-circuit is what you mean.
Differences are negligible in real apps — pick the most readable. Classic for wins micro-benchmarks; for...of wins maintainability.
for (let i = 0; i < N; i++) — or [...Array(N).keys()] if you need an iterable of 0..N-1.