JavaScript Tutorial

While Loop in JavaScript: Syntax, Examples and Best Practices

Master the JavaScript while loop with clear syntax breakdown, real-world examples, loop control with break and continue, do...while comparison, common mistakes, and best practices.

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: 5

Syntax

while (condition) {
  // code to repeat
  // āš ļø must update something so the condition eventually becomes false!
}
  • condition — evaluated before every iteration; if true the body runs, if false the 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 → print 1 → i++ → i = 2
  • Step 2: Is 2 <= 4? āœ… Yes → run body → print 2 → i++ → i = 3
  • Step 3: Is 3 <= 4? āœ… Yes → run body → print 3 → i++ → i = 4
  • Step 4: Is 4 <= 4? āœ… Yes → run body → print 4 → 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++;
}
SituationBest Choice
You know exactly how many times to loopfor āœ…
You loop until something changeswhile āœ…
Iterating over an array by indexfor āœ…
Waiting for user input or external eventwhile āœ…
Retry logic until successwhile āœ…
Counting with a fixed rangefor āœ…

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 512

Example 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: 54321

Example 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: 3

continue — 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: ₹2750

The 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  5

Mistake 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  6

Mistake 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.js

Expected 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

  1. āœ… Always initialize variables before the while condition
  2. āœ… Always update the variable the condition depends on — inside the loop body
  3. āœ… When using continue, update the counter before the continue statement
  4. āœ… Use while (true) with a clear break — it's clean for open-ended loops
  5. āœ… Add a safety counter for risky loops to prevent infinite hangs
  6. āœ… If you know the count upfront, prefer for — it's more readable
  7. āœ… Keep the loop body focused — one responsibility per loop
  8. āœ… Prefer while for 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! šŸ’Ŗ