Loops: while & for
Repeat JavaScript code safely with while, do...while, for, break, continue, labels, and guardrails that prevent infinite loops.
- 01Choose the right loop shapeUse
while,do...while, orforbased on what you know before the loop starts. - 02Trace loop executionPredict initialization, condition checks, body runs, updates, and final output.
- 03Stop loops safelyUse
break,continue, labels, and safety guards without freezing a page.
Why loops exist
A loop repeats a block of code while a condition says to keep going. That one idea saves you from copying the same line again and again. Instead of writing ten console.log calls, you write one call inside a loop and let JavaScript run it repeatedly.
This lesson covers two beginner loop families. Use while when the number of repeats is not known yet: keep stirring until the sauce thickens. Use for when the loop has a clear counter: run five laps on a track. do...while is the special case where the body must run at least once before the condition is checked.
Repetition is useful only when each pass has a purpose. A loop needs a starting state, a question that eventually becomes false, and a body that makes progress toward that false answer.
- In real life: Fold one shirt, then ask if any shirts remain
- In JavaScript: A
whileloop: unknown number of repeats - In real life: Run exactly five laps with a lap counter
- In JavaScript: A
forloop: start, check, body, update - In real life: Taste the soup once before deciding
- In JavaScript: A
do...whileloop: body first, condition after
Where the analogy stops: A person can notice a chore is going nowhere. JavaScript keeps following the condition until your code changes it or exits, so loop safety matters.
You will step through real recorded code, change loop settings, sort scenarios by loop type, and practice with sums, FizzBuzz, off-by-one bugs, safety guards, and searches that stop early.
while and do...while
STEP THROUGHA while loop checks its condition before the body. If the condition is already false, the body runs zero times.
while (condition) {
// repeat this body while condition is true
}A do...while loop flips the order. It runs the body once, then checks the condition. That makes it useful for “try once, then maybe repeat” tasks, such as asking for input at least once.
do {
// runs at least once
} while (condition);Sometimes you do not know how many repeats are needed. You keep checking a visible condition: thin sauce, invalid input, a search that has not found its target yet.
- In real life: Stir while the sauce is thin
- In JavaScript:
while (thin) { stir(); } - In real life: Taste once before deciding whether to add salt
- In JavaScript:
do { taste(); } while (needsSalt);
Where the analogy stops: Real cooking uses judgment. JavaScript only sees the condition you wrote, so the body must update the value the condition reads.
In this replay, start both examples at 3. The while condition is false immediately, but do...while still increments once before checking.
Compare the first condition check. With a start of 3, while runs zero times, but do...while still runs its body once.
script
while (thick < 3) { thick++;}console.log("while: " + thick);let taste = 3;do { taste++;} while (taste < 3);console.log("do: " + taste);The do...while form ends with a semicolon after the condition: } while (condition);. Ordinary while and for blocks do not put a semicolon after their closing brace.
for loops: counter, condition, update
INTERACTIVEA for loop places the loop’s bookkeeping in one header. That header has three parts separated by semicolons:
| Part | When it runs | Example |
|---|---|---|
| Initializer | Once before the first check | let i = 0 |
| Condition | Before every possible body run | i < 3 |
| Update | After each completed body run | i++ |
Read for (let i = 0; i < 3; i++) as: start the counter at 0; keep going while it is less than 3; after each lap, add 1. The body runs with i equal to 0, 1, and 2, then stops when the check sees 3.
A for loop is a track with a lap counter. Predict the printed total, then step through: initialize once, check, body, update, check again.
script
for (let i = 0; i < 3; i++) { total += i;}console.log(total);The timeline below shows the same anatomy without every value change. Use it to memorize the order: initializer once, condition, body, update, condition again.
let total = 0;for (let i = 1; i <= 3; i++) { total += i;}console.log(total);- init total=0
- init i=1
- check i=1: true
- body total=1
- update i becomes 2
- check i=2: true
- body total=3
- update i becomes 3
- check i=3: true
- body total=6
- update i becomes 4
- check i=4: false
Now showing: init total=0. Notice that the update waits until after the body.
Arrays get a full lesson in Stage 3, but you can already read this: scores.length is how many items are in the array, and scores[i] reads the item at index i. Indexes start at 0, so i < scores.length stops at the last valid index.
const scores = [8, 10, 6];
let total = 0;
for (let i = 0; i < scores.length; i++) {
total += scores[i];
}
console.log(total);The next lesson, for...of & for...in, teaches the friendlier collection loops. For now, know that a plain for loop is still useful when you need the index itself.
break and continue
STEP THROUGHbreak leaves the loop immediately. Think emergency exit. continue skips the rest of the current lap and jumps to the loop’s update/check step. Think skipping a song on a playlist: the playlist continues, but this song is over.
In the replay, odd numbers are skipped with continue. The first even multiple of 7 prints, then break stops the search.
Watch continue skip odd numbers and break stop as soon as the first even multiple of 7 is found.
script
if (n % 2 === 1) continue; if (n % 7 === 0) { console.log(n); break; }}| Statement | Meaning | Common use |
|---|---|---|
break | Leave this loop now | Stop after finding the first match |
continue | Skip the rest of this lap | Ignore values you do not want to process |
Labeled statements
RARE TOOLA label is a name followed by a colon before a statement. With loops, labels let break or continue point at an outer loop instead of only the nearest loop. They are legal JavaScript, but rare. Often, putting the nested loop in a function and using return is clearer.
Labels are rare, but they can name an outer loop. Step through a grid search that leaves both loops when it finds a match.
script
for (let col = 1; col <= 3; col++) { if (row * col === 6) { console.log(row + "," + col); break outer; } }}continue outer also exists. It skips to the next lap of the labeled outer loop. Use it sparingly; if a label makes you pause to understand the control flow, a helper function may be kinder.
outer: for (let row = 1; row <= 3; row++) {
for (let col = 1; col <= 3; col++) {
if (col === 2) continue outer;
console.log(row + "," + col);
}
}Avoiding infinite loops
SAFETYAn infinite loop is a treadmill with no stop button: JavaScript keeps running the loop and cannot return to the rest of the page. In a browser, a long loop can freeze the tab because the page’s JavaScript runs on the main thread, as introduced in the Engines, runtimes & hosts lesson.
Never demonstrate an infinite loop by actually running one. Use a guard: a maximum number of steps, a timeout, or a carefully bounded input size. This playground shows two risky patterns safely.
let i = 0;let steps = 0;while (i < 3) { steps++; // Bug: forgot i++ here. if (steps === 1000) { console.log("stopped by safety guard"); break; }}The buggy loop would keep going because i stays 0. A safety counter stopped it after 1000 steps and printed "stopped by safety guard".
Off-by-one: <= vs <
If indexes are 0, 1, and 2, then i < 3 is right. i <= 3 runs one extra time and may read past the end.
Updating the wrong variable
while (i < 3) must change i somehow. Updating j or forgetting the update means the question may stay true forever.
Floating-point equality
Decimal arithmetic like x += 0.1 is approximate. Prefer x >= 1 or count integer steps instead of waiting for x === 1.
Where you’ll use loops
Loops show up anywhere a program handles “many” things: attempts, rows, scores, characters, items in a cart, or search results. Here are practical patterns you will see often:
- Repeat a prompt or validation check until the answer is usable.
- Count from one number to another for a score, timer, or pagination control.
- Scan values until you find a match, then
break. - Skip values that do not matter with
continue. - Loop over simple arrays by index when the index matters.
- Count from 1 to 10 with a counter you can see up front
- Keep asking until the answer passes a validity check
- Read at least one line, then decide whether more lines remain
- Process every array item by index from
0toitems.length - 1 - Stir until the sauce is thick, however many stirs that takes
- Taste once, then keep tasting only while it still needs salt
Sort each scenario by the loop shape that communicates it best. The explanations name the clue to look for.
One famous footnote: the older var keyword behaves differently in loops when closures remember the loop variable. That trap is covered in the Closures lesson and the later closures-in-loops topic. In modern beginner code, prefer let in loop headers.
Common misconceptions
“A for loop always runs a fixed number of times.”
It often does, but break, changing the counter, or a condition based on changing data can stop it early or extend it.
“do...while is just another spelling of while.”
The first check is in a different place. while may run zero times; do...while runs at least once.
“continue exits the loop.”
continue exits only the current lap. break exits the loop.
“A frozen page means JavaScript crashed.”
It may simply be busy in a long loop. The browser cannot repaint or answer clicks until the loop gives control back.
“Labels are like goto.”
JavaScript labels do not jump anywhere by themselves. They only give break and continue a named target.
Practice: write and fix loops
6 EXERCISESPredict first, then run the code in your console or editor. Each task checks a small part of loop thinking.
How many times does the loop body run before the program prints?
let count = 0;
while (count < 3) {
count++;
}
console.log(count);The body runs while count < 3: starting at 0, it runs for 0, 1, and 2. After the third run, count is 3, so the next check is false.
Write a for loop that prints the sum of all numbers from 1 to 100.
let total = 0;
// write the loop here
console.log(total);let total = 0;
for (let n = 1; n <= 100; n++) {
total += n;
}
console.log(total);The counter visits every integer from 1 through 100. total += n adds each one to the running total, and the final sum is 5050.
Print 1 to 15. Multiples of 3 print Fizz, multiples of 5 print Buzz, and multiples of both print FizzBuzz.
for (let n = 1; n <= 15; n++) {
// print Fizz, Buzz, FizzBuzz, or n
}for (let n = 1; n <= 15; n++) {
if (n % 15 === 0) {
console.log("FizzBuzz");
} else if (n % 3 === 0) {
console.log("Fizz");
} else if (n % 5 === 0) {
console.log("Buzz");
} else {
console.log(n);
}
}Multiples of both 3 and 5 are multiples of 15, so that branch comes first. The last line for 15 is FizzBuzz.
The program should print only 0, 1, and 2. Which comparison operator fixes it?
for (let i = 0; i <= 3; i++) {
console.log(i);
}for (let i = 0; i < 3; i++) {
console.log(i);
}Indexes 0, 1, and 2 are three values. The condition i < 3 stops before the extra value 3 is printed.
Add a guard so this loop cannot run forever if ready never becomes true.
let tries = 0;
let ready = false;
while (!ready) {
tries++;
// add a guard that stops after 5 tries
}let tries = 0;
let ready = false;
while (!ready) {
tries++;
if (tries === 5) {
console.log("stopped by guard");
break;
}
}The guard makes progress visible even when ready never changes. After five laps it prints stopped by guard and break exits safely.
Search the array from left to right. Stop as soon as you find a negative number.
const numbers = [4, 9, 0, -3, 8];
let firstNegative = null;
// search here
console.log(firstNegative);const numbers = [4, 9, 0, -3, 8];
let firstNegative = null;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < 0) {
firstNegative = numbers[i];
break;
}
}
console.log(firstNegative);The loop checks each value in order. When it reaches -3, it stores that value and breaks, so later values are not examined.
Quiz: check your understanding
8 QUESTIONSRead every explanation, even for choices you do not pick.
Question 1 of 8When is a
whileloop's condition checked?Choose an answer to see the explanation.
Question 2 of 8What does the while loop print?
Read the code, then predictlet n = 3; while (n < 3) { n++; } console.log(n);Choose an answer to see the explanation.
Question 3 of 8What does the for loop total print?
Read the code, then predictlet total = 0; for (let i = 0; i < 3; i++) { total += i; } console.log(total);Choose an answer to see the explanation.
Question 4 of 8Which part of
for (let i = 0; i < 5; i++)runs only once?Choose an answer to see the explanation.
Question 5 of 8What do the continue examples print?
Read the code, then predictfor (let n = 1; n <= 5; n++) { if (n % 2 === 1) continue; console.log(n); }Choose an answer to see the explanation.
Question 6 of 8What does
breakdo inside a loop?Choose an answer to see the explanation.
Question 7 of 8Why can
while (x !== 1) { x += 0.1; }be dangerous?Choose an answer to see the explanation.
Question 8 of 8When are labels usually worth considering?
Choose an answer to see the explanation.
Key takeaways
whilechecks before the body;do...whilechecks after the body.- A
forheader shows initializer, condition, and update together. breakexits a loop;continueskips the rest of one lap.- Labels can aim
breakorcontinueat an outer loop, but they are rare. - Every loop needs progress toward stopping, plus guards when the stopping condition may fail.
Remember the one-liner.
A loop repeats a block while a condition allows it; safe loops make that condition eventually stop being true.
Up next: for...of & for...in.