Welcome back! š In the previous lesson, you mastered the for loop ā great for when you know exactly how many times to repeat. Now let's explore the while loop ā JavaScript's go-to when you don't know the count upfront and just want to keep going until something changes!
The while loop is simpler in structure but incredibly powerful. You'll find it in input validation, retry logic, game loops, real-time data processing, and much more.
Let's break it down completely!
What is a while Loop?
A while loop keeps repeating a block of code as long as its condition remains true. Unlike the for loop, it doesn't have a built-in counter ā you're in full control of what keeps it running and what makes it stop.
let count = 1;
while (count <= 5) {
console.log("Count:", count);
count++;
}
// Output:
// Count: 1
// Count: 2
// Count: 3
// Count: 4
// Count: 5Syntax
while (condition) {
// code to repeat
// ā ļø must update something so the condition eventually becomes false!
}conditionā evaluated before every iteration; iftruethe body runs, iffalsethe loop exits- loop body ā the block of code that repeats
- update ā unlike
for, there's no dedicated update slot ā you must handle it yourself inside the body
How JavaScript Executes a while Loop
let i = 1;
while (i <= 4) {
console.log(i);
i++;
}Step by step:
- Step 1: Is
1 <= 4? ā Yes ā run body ā print1āi++ā i =2 - Step 2: Is
2 <= 4? ā Yes ā run body ā print2āi++ā i =3 - Step 3: Is
3 <= 4? ā Yes ā run body ā print3āi++ā i =4 - Step 4: Is
4 <= 4? ā Yes ā run body ā print4āi++ā i =5 - Step 5: Is
5 <= 4? ā No ā exit loop
The key difference from for: the condition is checked first, before the body ever runs. If the condition is false from the very beginning, the body never executes.
let x = 10;
while (x < 5) {
console.log("This never runs"); // Condition false from start
}
console.log("Loop was skipped ā
");
// Output: Loop was skipped ā
while vs for ā Which to Use?
Both loops can do the same job, but each shines in different situations.
// Same result ā two different tools
// for loop ā when count is known
for (let i = 1; i <= 5; i++) {
console.log(i);
}
// while loop ā when count is unknown or condition-driven
let i = 1;
while (i <= 5) {
console.log(i);
i++;
}| Situation | Best Choice |
|---|---|
| You know exactly how many times to loop | for ā
|
| You loop until something changes | while ā
|
| Iterating over an array by index | for ā
|
| Waiting for user input or external event | while ā
|
| Retry logic until success | while ā
|
| Counting with a fixed range | for ā
|
Real-World Examples
Example 1: Number Doubling
let num = 1;
console.log("Doubling until over 1000:");
while (num <= 1000) {
process.stdout.write(num + " ");
num *= 2;
}
// Output: 1 2 4 8 16 32 64 128 256 512Example 2: Reverse a Number
let number = 12345;
let reversed = 0;
while (number > 0) {
let digit = number % 10; // Get last digit
reversed = reversed * 10 + digit; // Append to reversed
number = Math.floor(number / 10); // Remove last digit
}
console.log("Reversed:", reversed);
// Output: Reversed: 54321Example 3: Sum of Digits
let num = 9876;
let sum = 0;
while (num > 0) {
sum += num % 10; // Add last digit to sum
num = Math.floor(num / 10); // Remove last digit
}
console.log("Sum of digits:", sum);
// Output: Sum of digits: 30 (9+8+7+6)Example 4: Simulated Login with Retry
const correctPin = "1234";
const attempts = ["0000", "9999", "1234"]; // Simulated user inputs
let tries = 0;
let accessGranted = false;
while (tries < attempts.length) {
let input = attempts[tries];
tries++;
if (input === correctPin) {
accessGranted = true;
console.log(`ā
Access granted on attempt ${tries}!`);
break;
} else {
console.log(`ā Attempt ${tries}: Wrong PIN "${input}"`);
}
}
if (!accessGranted) {
console.log("š Account locked ā too many failed attempts.");
}
// Output:
// ā Attempt 1: Wrong PIN "0000"
// ā Attempt 2: Wrong PIN "9999"
// ā
Access granted on attempt 3!Example 5: Collatz Sequence
// The Collatz conjecture ā every number eventually reaches 1
// If even: divide by 2. If odd: multiply by 3 and add 1.
let n = 27;
let steps = 0;
console.log(`Collatz sequence starting at ${n}:`);
process.stdout.write(n + " ");
while (n !== 1) {
if (n % 2 === 0) {
n = n / 2;
} else {
n = n * 3 + 1;
}
process.stdout.write(n + " ");
steps++;
}
console.log(`\nReached 1 in ${steps} steps!`);
// Output: 27 82 41 124 62 31 94 47 142 ... 1
// Reached 1 in 111 steps!break ā Exit the Loop Early
Use break to stop the while loop the moment you have what you need.
// Find first number divisible by both 7 and 11
let num = 1;
while (num <= 1000) {
if (num % 7 === 0 && num % 11 === 0) {
console.log(`First number divisible by 7 and 11: ${num}`);
break;
}
num++;
}
// Output: First number divisible by 7 and 11: 77// Stop processing orders when stock runs out
let stock = 5;
let orders = [1, 2, 1, 3, 2, 1]; // units per order
let processed = 0;
while (orders.length > 0) {
let order = orders.shift(); // Take first order
if (order > stock) {
console.log(`ā Cannot fulfill order of ${order} ā only ${stock} left.`);
break;
}
stock -= order;
processed++;
console.log(`ā
Order of ${order} fulfilled. Stock remaining: ${stock}`);
}
console.log(`\nTotal orders processed: ${processed}`);
// Output:
// ā
Order of 1 fulfilled. Stock remaining: 4
// ā
Order of 2 fulfilled. Stock remaining: 2
// ā
Order of 1 fulfilled. Stock remaining: 1
// ā Cannot fulfill order of 3 ā only 1 left.
// Total orders processed: 3continue ā Skip an Iteration
Use continue to skip the current iteration and jump back to the condition check.
// Print only numbers NOT divisible by 3
let i = 1;
while (i <= 15) {
if (i % 3 === 0) {
i++;
continue; // ā ļø Must increment BEFORE continue ā or infinite loop!
}
process.stdout.write(i + " ");
i++;
}
// Output: 1 2 4 5 7 8 10 11 13 14// Process valid transactions only
let transactions = [500, -100, 250, 0, 800, -50, 1200];
let index = 0;
let total = 0;
while (index < transactions.length) {
let amount = transactions[index];
index++;
if (amount <= 0) {
console.log(`Skipping invalid transaction: ā¹${amount}`);
continue;
}
total += amount;
console.log(`ā
Processed: ā¹${amount} | Running total: ā¹${total}`);
}
console.log(`\nFinal Total: ā¹${total}`);
// Output:
// ā
Processed: ā¹500 | Running total: ā¹500
// Skipping invalid transaction: ā¹-100
// ā
Processed: ā¹250 | Running total: ā¹750
// Skipping invalid transaction: ā¹0
// ā
Processed: ā¹800 | Running total: ā¹1550
// Skipping invalid transaction: ā¹-50
// ā
Processed: ā¹1200 | Running total: ā¹2750
// Final Total: ā¹2750The Infinite Loop ā and How to Avoid It
An infinite loop runs forever because the condition never becomes false. It freezes your program and crashes it.
// ā Infinite loop ā i never changes!
let i = 0;
while (i < 5) {
console.log(i);
// Forgot i++ ā runs forever!
}
// ā Infinite loop ā condition is always true
while (true) {
console.log("forever...");
// No break ā never stops!
}How to Prevent Infinite Loops
// ā
Always update the variable that the condition depends on
let i = 0;
while (i < 5) {
console.log(i);
i++; // ā
i grows ā condition will eventually be false
}
// ā
When using while (true), ALWAYS have a break condition
let attempts = 0;
while (true) {
attempts++;
console.log("Attempt:", attempts);
if (attempts >= 3) break; // ā
Will definitely exit
}The while (true) Pattern
Sometimes an intentional infinite loop with a break is perfectly clean and readable:
let queue = ["Task A", "Task B", "Task C"];
while (true) {
if (queue.length === 0) {
console.log("ā
All tasks completed!");
break;
}
let task = queue.shift();
console.log(`Processing: ${task}`);
}
// Output:
// Processing: Task A
// Processing: Task B
// Processing: Task C
// ā
All tasks completed!Common Mistakes
Mistake 1: Forgetting to Update the Variable
let count = 1;
// ā count never changes ā infinite loop!
while (count <= 5) {
console.log(count);
// forgot count++
}
// ā
Always update inside the body
while (count <= 5) {
console.log(count);
count++; // ā
}Mistake 2: Updating After continue ā Causes Infinite Loop
let i = 1;
// ā When i === 3, continue jumps back BEFORE i++ ā i stays 3 forever!
while (i <= 5) {
if (i === 3) continue; // Jumps back ā i never becomes 4!
console.log(i);
i++;
}
// ā
Always increment BEFORE continue
while (i <= 5) {
if (i === 3) {
i++; // ā
Update first
continue;
}
console.log(i);
i++;
}
// Output: 1 2 4 5Mistake 3: Wrong Condition Direction
let i = 10;
// ā Condition is already false from the start ā body never runs
while (i < 5) {
console.log(i); // Never executes
i--;
}
// ā
Condition matches the direction of change
while (i > 5) {
console.log(i);
i--; // Counting down toward 5
}
// Output: 10 9 8 7 6Mistake 4: Checking Condition Before It's Set Up
// ā user is never defined before the condition ā always undefined
while (user !== "quit") {
// This crashes ā user is not declared!
}
// ā
Initialize variables before the while condition
let user = "";
while (user !== "quit") {
user = "quit"; // Simulate input
console.log("User entered:", user);
}Practical Exercise
Create a file called while-loop.js:
// šÆ While Loop Practice
// 1. Fibonacci Sequence up to 1000
console.log("=== Fibonacci Sequence up to 1000 ===");
let a = 0, b = 1;
while (a <= 1000) {
process.stdout.write(a + " ");
let next = a + b;
a = b;
b = next;
}
console.log();
// 2. Find all factors of a number
function findFactors(num) {
console.log(`\n=== Factors of ${num} ===`);
let i = 1;
let factors = [];
while (i <= num) {
if (num % i === 0) {
factors.push(i);
}
i++;
}
console.log(factors.join(", "));
}
findFactors(36);
findFactors(100);
// 3. ATM Withdrawal Simulation
console.log("\n=== ATM Simulation ===");
let balance = 5000;
let withdrawals = [1000, 2000, 500, 3000]; // Simulated withdrawal requests
let w = 0;
while (w < withdrawals.length) {
let amount = withdrawals[w];
w++;
if (amount > balance) {
console.log(`ā Cannot withdraw ā¹${amount} ā insufficient balance (ā¹${balance})`);
continue;
}
balance -= amount;
console.log(`ā
Withdrew ā¹${amount} | Remaining balance: ā¹${balance}`);
}
console.log(`\nFinal Balance: ā¹${balance}`);
// 4. Guess the number simulation with while
console.log("\n=== Guessing Game Simulation ===");
let secret = 63;
let guesses = [20, 80, 50, 70, 60, 63];
let attempt = 0;
while (attempt < guesses.length) {
let guess = guesses[attempt];
attempt++;
if (guess < secret) {
console.log(`Attempt ${attempt}: ${guess} ā Too low ā¬ļø`);
} else if (guess > secret) {
console.log(`Attempt ${attempt}: ${guess} ā Too high ā¬ļø`);
} else {
console.log(`Attempt ${attempt}: ${guess} ā š Correct! Found in ${attempt} attempts.`);
break;
}
}Run it:
node while-loop.jsExpected Output:
=== Fibonacci Sequence up to 1000 ===
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
=== Factors of 36 ===
1, 2, 3, 4, 6, 9, 12, 18, 36
=== ATM Simulation ===
ā
Withdrew ā¹1000 | Remaining balance: ā¹4000
ā
Withdrew ā¹2000 | Remaining balance: ā¹2000
ā
Withdrew ā¹500 | Remaining balance: ā¹1500
ā Cannot withdraw ā¹3000 ā insufficient balance (ā¹1500)
Final Balance: ā¹1500
=== Guessing Game Simulation ===
Attempt 1: 20 ā Too low ā¬ļø
Attempt 2: 80 ā Too high ā¬ļø
Attempt 3: 50 ā Too low ā¬ļø
Attempt 4: 70 ā Too high ā¬ļø
Attempt 5: 60 ā Too low ā¬ļø
Attempt 6: 63 ā š Correct! Found in 6 attempts.Key Takeaways
Congratulations! š You now fully understand the while loop in JavaScript.
ā
while loop is best when you don't know the number of iterations upfront ā you loop until a condition changes.
ā Condition checked first ā if it's false from the start, the body never runs at all.
ā
You control the update ā unlike for, there's no dedicated update slot. You must update the condition variable inside the body yourself.
ā
break exits the loop immediately when you're done.
ā
continue skips the current iteration ā but always update the counter before continue to avoid an infinite loop.
ā
while (true) with break is a valid and clean pattern for task queues, menus, and retry logic.
ā
Infinite loops happen when the condition never becomes false ā always make sure something in your loop moves it toward false.
Best Practices
- ā
Always initialize variables before the
whilecondition - ā Always update the variable the condition depends on ā inside the loop body
- ā
When using
continue, update the counter before thecontinuestatement - ā
Use
while (true)with a clearbreakā it's clean for open-ended loops - ā Add a safety counter for risky loops to prevent infinite hangs
- ā
If you know the count upfront, prefer
forā it's more readable - ā Keep the loop body focused ā one responsibility per loop
- ā
Prefer
whilefor retry logic, polling, and condition-driven iteration
What's Next?
Great work! š You've mastered the while loop ā perfect for open-ended, condition-driven repetition.
Next up, let's explore the Do While Loop ā ā similar to while, but with one important twist: it always runs the body at least once, even if the condition is false from the start!
Let's keep going! šŖ