Q1If a while loop starts with its condition true and the body never changes the variable the condition checks, what happens?
Looping on a Condition — while, do...while, break, and continue
Learn JavaScript's while and do...while: looping when you can't know the count in advance, avoiding infinite loops, and when to use continue vs. break.
Moving people off a waitlist as reservation slots open up, or buying more of something as long as your balance covers it — for tasks like these, you know when to stop, but you can't tell in advance how many times to repeat.
This article covers while and do...while, which repeat based on a condition, continue, which skips a pass, and break, which exits the loop.
Repeating Without a Fixed Count — while and Updating the Condition
Say some seats open up, and you want to move people up from the front of the waitlist in order. Each person you move up takes one seat, and you stop once there are 0 seats left. What stops the loop is a state — "while there are open seats" — not a number of passes, so a counting for loop doesn't express it naturally.
A while loop (a statement that repeats the body in curly braces as long as the condition in parentheses is true) takes only a condition in its parentheses. The condition is checked on every pass, before entering the body.
You set the starting value yourself before the loop, and you update the variable the condition checks yourself, inside the body.
const waitingList = ["Alice", "Bob", "Carol"]; // waitlist
let openSeats = 2; // open seats
// Move people up only while there are open seats
while (openSeats > 0) {
const name = waitingList.shift();
openSeats--; // same as openSeats = openSeats - 1
console.log(`${name} moved up (seats left: ${openSeats})`);
}
// Alice moved up (seats left: 1)
// Bob moved up (seats left: 0)
console.log(`Still waiting: ${waitingList.length}`); // Still waiting: 1
In a for loop, the update expression has a fixed place inside the parentheses, but with while you decide where in the body to put it. The flip side of that freedom is that nothing stops you from forgetting it: the code is still perfectly valid without the update.
Forget the Update and the Loop Never Stops
If the condition never becomes false, the body repeats forever. If you forget to write openSeats--, the seat count stays at 2, so the check always gives the same result. The console shows a timeout after 15 seconds, but the loop doesn't stop, and the other exercises won't work either until you reload the page. Always change the variable the condition checks somewhere in the body.
Running Once First — The Order of Checks in do...while
When a notification fails to send, you retry a few times until it succeeds. You have to send at least once before there's a result to check, but while checks its condition before entering the body, so depending on the starting value of the variable in the condition, the loop can end without sending anything.
A do...while loop (a statement that runs the body once and then checks the condition) is written as do { body } while (condition);, and everything up to the final semicolon is one statement. Since the check comes after the body, the body runs once even if the condition is false from the start.
const attempts = [false, false, true]; // send results prepared in advance (true means success)
let sent = true; // left over as true from the previous notification
let tried = 0;
// while checks first, so it ends without sending even once
while (!sent && tried < attempts.length) {
sent = attempts[tried];
tried++;
}
console.log(`Sends with while: ${tried}`); // Sends with while: 0
// do...while sends the first time before checking, then uses the result to decide whether to continue
do {
sent = attempts[tried];
tried++;
console.log(`Attempt ${tried}: ${sent ? "succeeded" : "failed"}`);
} while (!sent && tried < attempts.length);
// Attempt 1: failed / Attempt 2: failed / Attempt 3: succeeded
sent still true. while ends after just the check, while do...while sends once and then decides whether to continue.Only the first pass skips the check; after that, the loop repeats only while the condition is true, just like while. If you don't want the body to run at all when the condition is false, choose while. If you want it to run once before you look at the result, choose do...while.
Skipping Just One Pass — When to Use continue
When you go down a shipping list from the top, you'll want to skip any line that's out of stock and move on to the next. The more skip conditions you add, the deeper the if braces get, and the shipping code you actually care about ends up buried inside them.
With continue (a statement that skips the rest of the current pass and moves on to the next one), you can cut a pass short as soon as it hits a condition you want to skip. The loop itself keeps going, so the next pass starts normally with the condition check.
const names = ["A5 planner", "Desk lamp", "USB hub"];
const stocks = [12, 0, 5]; // 0 means out of stock
let index = 0;
while (index < names.length) {
const name = names[index];
const stock = stocks[index];
index++; // advance first so continue can't skip it
// For out-of-stock lines, skip the rest of this pass and go to the next
if (stock === 0) {
console.log(`${name}: out of stock, skipped`);
continue;
}
console.log(`${name}: shipping ${stock}`);
}
// A5 planner: shipping 12
// Desk lamp: out of stock, skipped
// USB hub: shipping 5
| Line processed | Value of stock and the check | Result of that pass |
|---|---|---|
| Line 1: A5 planner | stock is 12, not 0 | Prints shipping 12 |
| Line 2: Desk lamp | stock is 0, so continue | The shipping line doesn't run |
| Line 3: USB hub | stock is 5, not 0 | Prints shipping 5 |
continue skips only the lines between it and the end of the body. You can use continue in the body of for and for...of too, and since the update expression in a for loop's parentheses sits outside the body, it still runs on a pass that hit continue.
continue Also Skips Your Update Line
If you put index++ after continue, index doesn't advance on the skipped pass. The next pass reads the same line again, stock is still 0, the condition doesn't change, and the loop never ends. Update the variable the condition checks before continue.
Stopping as Soon as You Find It — Where break Takes You
Say you want to scan a log from the top and find only the first error. If you keep reading to the end after finding it, that's wasted work, and depending on how you write it, a later error can overwrite firstError.
With break (a statement that immediately ends the loop it's in), you can exit the loop on the pass where the condition is met. It's the same statement you used to exit a switch in the article on conditionals. You'll use the value you found outside the loop, so declare firstError before the loop.
const logs = ["INFO Started", "WARN Slow response", "ERROR Payment failed", "ERROR Resend failed"];
let index = 0;
let firstError = "";
while (index < logs.length) {
const line = logs[index];
index++;
if (line.startsWith("ERROR")) {
firstError = line;
break; // found the first one, so don't check the rest
}
}
console.log(`First error: ${firstError}`); // First error: ERROR Payment failed
console.log(`Lines checked: ${index}`); // Lines checked: 3
const line = logs[index]— the line checked on this pass- After
break, execution leaves the braces and moves on to the nextconsole.logline
firstError = line— saves the line it foundbreak— exits the outer while, not these braces- Any lines below
breaknever run
break nor the remaining passes run. Execution continues on the line after the while loop's closing brace.Even on the pass that hits break, the index++ written before it has already run. So index stops at 3, and the "Lines checked: 3" printed after the loop matches the position of the line that was found, counting from 1.
Knowledge Check
Answer each question one by one.
Q2If the condition is false from the start, how many times does the body of a do...while run?
Q3What happens next when continue runs inside a loop?