Loops: for, while & do…while
Loops repeat code. Instead of writing the same line ten times, you write it once and tell JavaScript how many times to run it — or to keep going until some condition changes. This lesson covers the classic for, while and do…while loops, plus break and continue.
The for loop
for (let i = 1; i <= 5; i++) { console.log("Lap", i); }
Lap 1 Lap 2 Lap 3 Lap 4 Lap 5
The parentheses hold three parts, separated by semicolons:
- Initialisation —
let i = 1runs once, before the loop starts. - Condition —
i <= 5is checked before every pass; the loop stops when it's false. - Update —
i++runs after every pass.
Each pass is called an iteration. Counting from 0 with i < length is the standard way to loop over an array's positions:
const fruits = ["apple", "banana", "cherry"]; for (let i = 0; i < fruits.length; i++) { console.log(i, fruits[i]); }
0 apple 1 banana 2 cherry
Loops can count down or in steps, too: for (let i = 10; i > 0; i -= 2) visits 10, 8, 6, 4, 2.
The while loop
A while loop just has a condition. Use it when you don't know in advance how many iterations you'll need:
let balance = 1000; let years = 0; while (balance < 2000) { balance *= 1.07; years++; } console.log(`Doubled after ${years} years: $${balance.toFixed(2)}`);
Doubled after 11 years: $2104.85
The do…while loop
A do…while loop checks its condition after each pass, so the body always runs at least once:
let roll; let attempts = 0; const rolls = [3, 5, 6, 2]; do { roll = rolls[attempts]; attempts++; console.log("rolled", roll); } while (roll !== 6); console.log("Got a six after", attempts, "rolls");
rolled 3 rolled 5 rolled 6 Got a six after 3 rolls
break and continue
break exits the loop entirely. continue skips the rest of the current iteration and moves on to the next:
const numbers = [4, -1, 7, 0, 12, 99, 3]; for (let i = 0; i < numbers.length; i++) { const n = numbers[i]; if (n === 99) break; if (n <= 0) continue; console.log(n); }
4 7 12
Negative numbers and zero are skipped by continue; reaching 99 stops the loop, so 3 is never printed.
Nested loops and labels
A loop inside a loop runs the inner loop completely for every pass of the outer one:
for (let row = 1; row <= 3; row++) { let line = ""; for (let col = 1; col <= 3; col++) { line += String(row * col).padStart(4); } console.log(line); }
1 2 3 2 4 6 3 6 9
A plain break only exits the innermost loop. To break out of an outer loop, give it a label and use break label:
const grid = [[1, 2], [3, 42], [5, 6]]; search: for (let r = 0; r < grid.length; r++) { for (let c = 0; c < grid[r].length; c++) { if (grid[r][c] === 42) { console.log(`found at row ${r}, column ${c}`); break search; } } }
found at row 1, column 1
Infinite loops
If the condition never becomes false, the loop never ends and the page freezes. Typical causes: forgetting the update (i++), or updating the wrong variable. If a page hangs while you're testing, close the tab and check your loop's condition and update.
Which loop to use?
| Loop | Best for |
|---|---|
for | A known number of iterations, or when you need the index |
while | Repeating until something changes |
do…while | When the body must run at least once |
for…of | Visiting every item of an array or string (next lesson) |
| Array methods | forEach, map, filter… (lesson 31) |