Imagine you're filling a bath. You don't turn the tap on for "exactly 47 seconds" — you turn it on and keep it running while the bath isn't full yet, then stop the moment it is. You didn't count in advance; you watched a condition and repeated until it stopped being true.
That is a condition-controlled loop. In code it's written with the keyword
while:
The computer checks the condition. If it's true, it runs the block inside the curly braces, then loops back and checks again. As soon as the condition is false, it skips the block and carries on with the rest of the program. So the loop keeps going until the condition becomes false — however many times that takes.
You already know the for loop — which is perfect when you know
the number of repeats before you start ("do this 10 times", "for every pupil in the
class"). But loads of problems aren't like that:
In every case the number of repeats depends on what happens during the loop, so you
can't put a fixed count at the top. That's exactly when you reach for while.
Start with a number and keep halving it while it is still bigger than 1. How many halvings
will that take? It depends on the number — so we let the condition
Try changing 64 to 1000, or to 7. The loop runs a
different number of times each time — but you never had to work out that number
yourself. The condition did it for you.
Look back at that example and you'll spot the pattern that every safe while
loop follows. Miss any one of the three and the loop misbehaves.
let n = 64. The
condition needs a value to test.n = Math.floor(n / 2). Every
pass must nudge things towards making the condition false, or the loop never ends.That third part is the heart of it: something inside the loop must change so that the condition will eventually become false. If nothing changes, nothing ever stops.
A while loop doesn't have to count down. Here we start at 1 and keep
doubling while we're still at or below 100. We've no idea in advance how many
doublings that is — the loop finds out.
Notice the loop overshoots: it stops at 128, the first value greater than 100, because the
condition is only checked at the top of each pass. Once value becomes
128 the check while
loop.
Here's a countdown written with while. We keep printing and subtracting one
while the counter is still above zero.
This one could have been a for loop, because we happen to know it's 5 steps.
That's the honest truth about the two loops: many problems can be written either way, and a
while can always do a for's job. But when the number of repeats is
genuinely unknown until you run, only a condition-controlled loop fits comfortably.
Both loops repeat; they differ in what decides the stopping.
for) — you know the number of repeats up
front. "Do this for each of the 30 pupils." A counter marches through a fixed range.while) — you don't know the number
of repeats up front. "Keep going until the bath is full / the number reaches 1 / the password
is right." A condition, re-checked each pass, decides when to stop.
A handy rule of thumb: if you can finish the sentence "repeat exactly ___ times" with a
number, use for. If the best you can say is "repeat until ___", use
while.
The classic while bug is the infinite loop: if the condition
never becomes false, the loop never ends. Almost always it's because
the loop forgot to make progress — nothing inside it changes the thing the condition tests.
This countdown is broken because it prints forever without ever subtracting from
count:
In a real program an infinite loop makes the computer hang — it just sits there spinning, doing nothing useful, until you force-quit it. (In this Primer's Run boxes we cut a runaway loop off automatically after about a second, so you won't freeze your browser — but you'd get no "Lift-off", just a wall of the same number.)
The fix is always the same: make sure something inside the loop moves the condition
towards false. Before you run a while loop, ask yourself: "what changes
each pass, and will that eventually stop it?" Here the cure is a single line —
count = count - 1; — the very line the broken version left out.
Because while checks the condition before the first pass, a loop can run
zero times. If you write let n = 1; then while (n > 1)
{ ... }, the condition is false immediately, so the block is skipped entirely and never
runs once. That's not a bug — it's often exactly what you want (a "do it only if there's
anything to do" loop). It's another reason while is so flexible: it can run any
number of times from zero upwards.