Welcome back! š In the previous lesson, you mastered the while loop ā perfect for condition-driven repetition. Now let's explore its close cousin ā the do...while loop!
The do...while loop has one key superpower that sets it apart: it always runs the body at least once, no matter what. The condition is checked only after the first execution. This makes it the perfect tool for menus, prompts, validation, and any situation where "try it first, then decide" is the right approach.
Let's break it down completely!
What is a do...while Loop?
A do...while loop executes its body first, then checks the condition. If the condition is true, it repeats. If false, it stops ā but the body has already run at least once.
let count = 1;
do {
console.log("Count:", count);
count++;
} while (count <= 5);
// Output:
// Count: 1
// Count: 2
// Count: 3
// Count: 4
// Count: 5Syntax
do {
// code to repeat
// runs at least once ā ALWAYS!
} while (condition);do { }ā the body that always runs first, before any condition checkconditionā evaluated after the body runs; iftruethe body repeats, iffalsethe loop exits;ā don't forget the semicolon after the closingwhile (condition)ā it's required!
The Key Difference: Condition Checked After
This is what makes do...while unique. The condition sits at the bottom, not the top.
let x = 100; // Condition will be false immediately
// while ā checks condition FIRST, body never runs
while (x < 5) {
console.log("while body ran"); // Never prints
}
// do...while ā runs body FIRST, then checks condition
do {
console.log("do...while body ran"); // Prints ONCE ā
} while (x < 5);
// Output: do...while body ranThink of it this way:
whileā "Should I do this?" then do itdo...whileā "Do it!" then "Should I do it again?"
How JavaScript Executes a do...while Loop
let i = 1;
do {
console.log(i);
i++;
} while (i <= 4);Step by step:
- Step 1: Run body ā print
1ā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
Notice: the body ran before any condition was ever checked ā that's the do...while guarantee.
do...while vs while ā Side by Side
// Scenario: condition is FALSE from the very start
let n = 10;
// while ā body SKIPPED entirely
while (n < 5) {
console.log("while ran"); // Never executes
}
// do...while ā body runs ONCE regardless
do {
console.log("do...while ran"); // Runs once ā
} while (n < 5);| Feature | while | do...while |
|---|---|---|
| Condition checked | Before first run | After first run |
| Minimum executions | 0 (may never run) | 1 (always runs once) |
| Best for | Condition may be false upfront | Must run body at least once |
| Semicolon after | Not needed | Required after while(...) |
| Readability | Condition visible at top | Body intent clear first |
Real-World Examples
Example 1: Menu System
The most classic do...while use case ā show a menu at least once, then repeat based on the user's choice.
// Simulated user choices
let choices = [1, 2, 3, 4]; // 1=View, 2=Add, 3=Delete, 4=Exit
let step = 0;
let choice;
do {
choice = choices[step++];
console.log("\nš MAIN MENU");
console.log("1. View Items");
console.log("2. Add Item");
console.log("3. Delete Item");
console.log("4. Exit");
console.log(`\nYou chose: ${choice}`);
switch (choice) {
case 1: console.log("š Showing all items..."); break;
case 2: console.log("ā Adding new item..."); break;
case 3: console.log("šļø Deleting item..."); break;
case 4: console.log("š Goodbye!"); break;
default: console.log("ā Invalid choice. Try again.");
}
} while (choice !== 4);
// Output: Menu displays all 4 times, exits on choice 4Example 2: Input Validation (Simulate Until Valid)
// Simulated inputs ā first two invalid, third valid
let inputs = [-5, 0, 42];
let index = 0;
let userInput;
do {
userInput = inputs[index++];
console.log(`Input received: ${userInput}`);
if (userInput <= 0) {
console.log("ā Invalid! Please enter a positive number.\n");
}
} while (userInput <= 0);
console.log(`ā
Valid input accepted: ${userInput}`);
// Output:
// Input received: -5
// ā Invalid! Please enter a positive number.
//
// Input received: 0
// ā Invalid! Please enter a positive number.
//
// Input received: 42
// ā
Valid input accepted: 42Example 3: OTP Retry System
const correctOtp = "7291";
const otpAttempts = ["1234", "0000", "7291"]; // Simulated inputs
let otpIndex = 0;
let enteredOtp;
let maxTries = 3;
let tries = 0;
do {
enteredOtp = otpAttempts[otpIndex++];
tries++;
console.log(`OTP Attempt ${tries}: ${enteredOtp}`);
if (enteredOtp === correctOtp) {
console.log("ā
OTP Verified! Login successful.");
break;
} else {
console.log(`ā Wrong OTP. ${maxTries - tries} attempt(s) remaining.`);
}
} while (tries < maxTries);
if (enteredOtp !== correctOtp) {
console.log("š Account locked. Please request a new OTP.");
}
// Output:
// OTP Attempt 1: 1234
// ā Wrong OTP. 2 attempt(s) remaining.
// OTP Attempt 2: 0000
// ā Wrong OTP. 1 attempt(s) remaining.
// OTP Attempt 3: 7291
// ā
OTP Verified! Login successful.Example 4: Dice Roll Until Six
// Simulate rolling a dice until we get a 6
let roll;
let rollCount = 0;
let rolls = [2, 5, 1, 4, 3, 6]; // Simulated dice rolls
let rollIndex = 0;
do {
roll = rolls[rollIndex++];
rollCount++;
console.log(`Roll ${rollCount}: š² ${roll}`);
} while (roll !== 6);
console.log(`\nš Rolled a 6 after ${rollCount} attempt(s)!`);
// Output:
// Roll 1: š² 2
// Roll 2: š² 5
// Roll 3: š² 1
// Roll 4: š² 4
// Roll 5: š² 3
// Roll 6: š² 6
// š Rolled a 6 after 6 attempt(s)!Example 5: Download Retry with Backoff
// Retry a failed download up to 3 times
let downloadSuccess = false;
let attempt = 0;
let maxAttempts = 3;
// Simulate: first two fail, third succeeds
let results = [false, false, true];
do {
attempt++;
downloadSuccess = results[attempt - 1];
console.log(`š„ Download attempt ${attempt}...`);
if (downloadSuccess) {
console.log("ā
Download successful!");
} else {
console.log(`ā Failed. Retrying in ${attempt * 2}s...`);
}
} while (!downloadSuccess && attempt < maxAttempts);
if (!downloadSuccess) {
console.log("š« Download failed after 3 attempts. Please try again later.");
}
// Output:
// š„ Download attempt 1...
// ā Failed. Retrying in 2s...
// š„ Download attempt 2...
// ā Failed. Retrying in 4s...
// š„ Download attempt 3...
// ā
Download successful!break ā Exit the Loop Early
// Keep generating numbers until we hit a prime
let num = 20;
do {
num++;
let isPrime = true;
for (let i = 2; i < num; i++) {
if (num % i === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
console.log(`First prime after 20: ${num}`);
break; // Exit do...while as soon as we find it
}
} while (num < 100);
// Output: First prime after 20: 23continue ā Skip an Iteration
// Process a queue ā skip already-processed items
let queue = ["task-1", "DONE", "task-2", "DONE", "task-3"];
let qIndex = 0;
do {
let task = queue[qIndex];
qIndex++;
if (task === "DONE") {
console.log(`āļø Skipping completed task`);
continue;
}
console.log(`āļø Processing: ${task}`);
} while (qIndex < queue.length);
// Output:
// āļø Processing: task-1
// āļø Skipping completed task
// āļø Processing: task-2
// āļø Skipping completed task
// āļø Processing: task-3Common Mistakes
Mistake 1: Missing Semicolon After while(...)
// ā SyntaxError ā missing semicolon at the end
do {
console.log("hello");
} while (false) // ā missing ;
// ā
Semicolon is required
do {
console.log("hello");
} while (false); // ā
Mistake 2: Forgetting to Update the Condition Variable
let i = 1;
// ā i never changes ā infinite loop!
do {
console.log(i);
// forgot i++
} while (i <= 5);
// ā
Always update inside the body
do {
console.log(i);
i++; // ā
} while (i <= 5);Mistake 3: Using do...while When Body Shouldn't Run if False
let isAuthenticated = false;
// ā do...while runs the protected code ONCE even when not authenticated!
do {
console.log("š Loading dashboard..."); // Runs even though user isn't logged in!
} while (isAuthenticated);
// ā
Use while ā checks condition BEFORE running
while (isAuthenticated) {
console.log("š Loading dashboard..."); // Correctly skipped ā
}Mistake 4: Updating After continue ā Causes Infinite Loop
let i = 1;
// ā When i === 3, continue jumps back BEFORE i++ ā loops forever on 3!
do {
if (i === 3) continue; // i never increments past 3!
console.log(i);
i++;
} while (i <= 5);
// ā
Always increment BEFORE continue
do {
if (i === 3) {
i++; // ā
Update first
continue;
}
console.log(i);
i++;
} while (i <= 5);
// Output: 1 2 4 5Mistake 5: Confusing do...while with while for Zero-Run Scenarios
let score = 0;
// ā You expect this to be skipped ā but it runs once!
do {
console.log("Game over screen shown"); // Runs even with score 0
} while (score > 100);
// ā
If the body should be conditional from start, use while
while (score > 100) {
console.log("Game over screen shown"); // Correctly skipped ā
}Practical Exercise
Create a file called do-while-loop.js:
// šÆ Do...While Loop Practice
// 1. Number guessing game simulation
console.log("=== šÆ Number Guessing Game ===");
const target = 47;
const guesses = [10, 70, 40, 55, 47];
let gIndex = 0;
let guess;
let gAttempts = 0;
do {
guess = guesses[gIndex++];
gAttempts++;
if (guess < target) console.log(`Guess ${gAttempts}: ${guess} ā Too low ā¬ļø`);
else if (guess > target) console.log(`Guess ${gAttempts}: ${guess} ā Too high ā¬ļø`);
else console.log(`Guess ${gAttempts}: ${guess} ā š Correct!`);
} while (guess !== target && gIndex < guesses.length);
console.log(`Solved in ${gAttempts} attempt(s)!\n`);
// 2. ATM PIN entry simulation
console.log("=== š§ ATM PIN Entry ===");
const correctPin = "9876";
const pinAttempts = ["1111", "0000", "9876"];
let pinIndex = 0;
let pin;
let pinTries = 0;
const maxPinTries = 3;
do {
pin = pinAttempts[pinIndex++];
pinTries++;
if (pin === correctPin) {
console.log(`ā
PIN accepted on attempt ${pinTries}. Welcome!`);
} else {
console.log(`ā Wrong PIN (Attempt ${pinTries}/${maxPinTries})`);
}
} while (pin !== correctPin && pinTries < maxPinTries);
if (pin !== correctPin) {
console.log("š Card blocked after 3 wrong attempts.\n");
}
// 3. Survey Form Simulation
console.log("=== š Survey Form ===");
const questions = [
{ q: "How satisfied are you? (1-5)", answer: 4 },
{ q: "Would you recommend us? (1-5)", answer: 5 },
{ q: "Rate our support (1-5)", answer: 3 },
];
let qIndex = 0;
let totalRating = 0;
do {
let current = questions[qIndex];
totalRating += current.answer;
console.log(`Q${qIndex + 1}: ${current.q}`);
console.log(`Answer: ${current.answer}/5\n`);
qIndex++;
} while (qIndex < questions.length);
let avgRating = (totalRating / questions.length).toFixed(1);
console.log(`š Average Rating: ${avgRating}/5`);
console.log(avgRating >= 4 ? "š Excellent feedback!" : "š Room for improvement.");Run it:
node do-while-loop.jsExpected Output:
=== šÆ Number Guessing Game ===
Guess 1: 10 ā Too low ā¬ļø
Guess 2: 70 ā Too high ā¬ļø
Guess 3: 40 ā Too low ā¬ļø
Guess 4: 55 ā Too high ā¬ļø
Guess 5: 47 ā š Correct!
Solved in 5 attempt(s)!
=== š§ ATM PIN Entry ===
ā Wrong PIN (Attempt 1/3)
ā Wrong PIN (Attempt 2/3)
ā
PIN accepted on attempt 3. Welcome!
=== š Survey Form ===
Q1: How satisfied are you? (1-5)
Answer: 4/5
Q2: Would you recommend us? (1-5)
Answer: 5/5
Q3: Rate our support (1-5)
Answer: 3/5
š Average Rating: 4.0/5
š Excellent feedback!Key Takeaways
Congratulations! š You now fully understand the do...while loop in JavaScript.
ā
do...while always runs the body at least once ā the condition is checked after the first execution.
ā Condition at the bottom ā body runs first, then condition decides if it repeats.
ā
Semicolon required ā always end with } while (condition);
ā Best suited for:
- Menu systems that must display before getting input
- Input validation ā try first, validate after
- Retry logic ā attempt first, check success after
- Any scenario where "run once, then decide" is the right approach
ā
Avoid do...while when the body should be completely skipped if the condition is false from the start ā use while instead.
ā
break exits early. continue skips to next iteration ā always update the counter before continue.
Best Practices
- ā
Always add a semicolon after
} while (condition);ā it's easy to forget - ā
Use
do...whilewhen the body must run at least once by design - ā
Use
whilewhen the body should be skippable ā don't force a run unnecessarily - ā Always update the condition variable inside the body to avoid infinite loops
- ā
When using
continue, update the counter before thecontinuestatement - ā Keep the body focused ā one clear purpose per loop
- ā Add a max attempts guard for retry-style loops to prevent runaway execution
- ā
Use
do...whilefor menus, OTP retries, validation prompts ā it reads naturally
What's Next?
Great work! š You've mastered the do...while loop ā the perfect tool for "try first, decide after" patterns.
Next up, let's explore the For...of Loop ā ā the cleanest way to loop over values of arrays, strings, and other iterables without worrying about indexes at all!
Let's keep going! šŖ