JavaScript While Loop
While Loop Basics
The while loop is a fundamental control flow statement that allows code to be executed repeatedly based on a given boolean condition. Unlike for loops, while loops are ideal when the number of iterations is unknown beforehand and depends on dynamic conditions.
1// Basic while loop syntax
2let counter = 0;
3while (counter < 3) {
4 console.log("Counter: " + counter);
5 counter++;
6}
7// Output: Counter: 0, Counter: 1, Counter: 2
8
9// Execution flow breakdown:
10// 1. Initialize counter = 0
11// 2. Check condition: counter < 3 → true
12// 3. Execute code block: console.log("Counter: 0")
13// 4. Increment counter: counter becomes 1
14// 5. Check condition: counter < 3 → true
15// 6. Execute code block: console.log("Counter: 1")
16// 7. Increment counter: counter becomes 2
17// 8. Check condition: counter < 3 → true
18// 9. Execute code block: console.log("Counter: 2")
19// 10. Increment counter: counter becomes 3
20// 11. Check condition: counter < 3 → false → EXIT LOOP
21
22// More examples:
23let number = 5;
24while (number > 0) {
25 console.log("Countdown: " + number);
26 number--;
27}
28// Output: Countdown: 5, Countdown: 4, Countdown: 3, Countdown: 2, Countdown: 1
29
30let total = 0;
31while (total < 10) {
32 total += 2;
33 console.log("Running total: " + total);
34}
35// Output: Running total: 2, Running total: 4, Running total: 6, Running total: 8, Running total: 10While Loop Core Characteristics
Condition-First- Condition is checked BEFORE each iteration, loop may not run at allIndefinite Iteration- Perfect when number of iterations is unknown in advanceManual Control- You must manually manage loop variables and exit conditionsEvent-Driven- Ideal for waiting for external events or conditions
While Loop Syntax and Structure
Understanding the complete syntax and structure of while loops is essential for writing effective conditional iteration logic. The while statement consists of a condition and a code block that executes as long as the condition remains true.
1// Complete while loop syntax breakdown
2
3// 1. Basic while loop
4let count = 0;
5while (count < 3) {
6 console.log("Basic: " + count);
7 count++;
8}
9
10// 2. Complex condition while loop
11let x = 0, y = 10;
12while (x < 5 && y > 0) {
13 console.log(`x: ${x}, y: ${y}`);
14 x++;
15 y--;
16}
17// Output: x: 0, y: 10; x: 1, y: 9; x: 2, y: 8; x: 3, y: 7; x: 4, y: 6
18
19// 3. Function-based condition
20function shouldContinue(attempts) {
21 return attempts < 3;
22}
23
24let attempts = 0;
25while (shouldContinue(attempts)) {
26 console.log("Attempt: " + attempts);
27 attempts++;
28}
29// Output: Attempt: 0, Attempt: 1, Attempt: 2
30
31// 4. Object property condition
32let user = { loginAttempts: 0, isLocked: false };
33while (user.loginAttempts < 3 && !user.isLocked) {
34 console.log("Login attempt: " + user.loginAttempts);
35 user.loginAttempts++;
36}
37// Output: Login attempt: 0, Login attempt: 1, Login attempt: 2
38
39// 5. String processing while loop
40let text = "Hello";
41let index = 0;
42while (index < text.length) {
43 console.log(`Character ${index}: '${text[index]}'`);
44 index++;
45}
46// Output: Character 0: 'H', Character 1: 'e', Character 2: 'l', Character 3: 'l', Character 4: 'o'
47
48// 6. Array processing while loop
49let numbers = [10, 20, 30, 40];
50let pos = 0;
51while (pos < numbers.length) {
52 console.log("Number at position " + pos + ": " + numbers[pos]);
53 pos++;
54}
55// Output: Number at position 0: 10, Number at position 1: 20, etc.
56
57// 7. Multiple variable updates
58let a = 0, b = 100;
59while (a < b) {
60 console.log(`a=${a}, b=${b}, difference=${b - a}`);
61 a += 10;
62 b -= 5;
63}
64// Continues until a >= b
65
66// 8. Mathematical condition
67let value = 1;
68while (value < 1000) {
69 console.log("Value: " + value);
70 value *= 2;
71}
72// Output: Value: 1, Value: 2, Value: 4, Value: 8, Value: 16, Value: 32, Value: 64, Value: 128, Value: 256, Value: 512
73
74// Syntax rules:
75// - Condition in parentheses after 'while'
76// - Code block in curly braces {}
77// - Condition must eventually become false to avoid infinite loops
78// - Loop variables must be initialized before the loop
79// - Loop variables must be updated inside the loopWhile Loop Syntax Components
while (condition)- Condition is evaluated before each iteration, loop runs if trueVariable Initialization- Loop variables must be declared and initialized before loop startsCondition Evaluation- Boolean expression that determines if loop continuesVariable Update- Loop variables must be updated inside loop body to ensure termination
Do-While Loop Variation
The do-while loop is a variation that guarantees the loop body executes at least once, as the condition is checked after the code block. This is useful when you need to execute code before checking the exit condition.
1// Do-while loop syntax and examples
2
3// 1. Basic do-while loop
4let counter = 0;
5do {
6 console.log("Do-while counter: " + counter);
7 counter++;
8} while (counter < 3);
9// Output: Do-while counter: 0, Do-while counter: 1, Do-while counter: 2
10
11// 2. Do-while vs while comparison
12console.log("=== WHILE LOOP (may not run) ===");
13let whileCount = 5;
14while (whileCount < 3) {
15 console.log("While loop: " + whileCount);
16 whileCount++;
17}
18// No output - condition false from start
19
20console.log("=== DO-WHILE LOOP (runs at least once) ===");
21let doWhileCount = 5;
22do {
23 console.log("Do-while loop: " + doWhileCount);
24 doWhileCount++;
25} while (doWhileCount < 3);
26// Output: Do-while loop: 5 (runs once even though condition is false)
27
28// 3. User input simulation with do-while
29let userInput = "";
30let attempts = 0;
31
32do {
33 // Simulate getting user input
34 attempts++;
35 userInput = attempts === 1 ? "" : "quit"; // Simulate first empty, then "quit"
36
37 if (userInput === "") {
38 console.log("Please enter a value (attempt " + attempts + ")");
39 }
40} while (userInput === "" && attempts < 3);
41// Output: Please enter a value (attempt 1), Please enter a value (attempt 2)
42
43// 4. Menu system with do-while
44let choice = "";
45do {
46 // Display menu
47 console.log("\n=== MENU ===");
48 console.log("1. View profile");
49 console.log("2. Edit settings");
50 console.log("3. Exit");
51
52 // Simulate user choice
53 choice = choice === "" ? "1" : "3"; // First view profile, then exit
54
55 switch (choice) {
56 case "1":
57 console.log("Displaying profile...");
58 break;
59 case "2":
60 console.log("Opening settings...");
61 break;
62 case "3":
63 console.log("Goodbye!");
64 break;
65 default:
66 console.log("Invalid choice");
67 }
68} while (choice !== "3");
69// Output: Menu, "Displaying profile...", Menu, "Goodbye!"
70
71// 5. Data validation with do-while
72let age;
73do {
74 // Simulate getting age input
75 age = age === undefined ? -5 : 25; // First invalid, then valid
76
77 if (age < 0 || age > 120) {
78 console.log("Invalid age: " + age + ". Please enter age between 0-120.");
79 }
80} while (age < 0 || age > 120);
81
82console.log("Valid age entered: " + age);
83// Output: Invalid age: -5. Please enter age between 0-120.
84// Valid age entered: 25
85
86// 6. Mathematical sequence with do-while
87let number = 2;
88do {
89 console.log("Number: " + number);
90 number = Math.pow(number, 2); // Square the number
91} while (number < 1000);
92// Output: Number: 2, Number: 4, Number: 16, Number: 256
93
94// 7. File/stream processing simulation
95let dataAvailable = false;
96let chunksProcessed = 0;
97
98do {
99 // Simulate processing data chunks
100 chunksProcessed++;
101 console.log("Processing chunk " + chunksProcessed);
102
103 // Simulate checking if more data available
104 dataAvailable = chunksProcessed < 3; // Process 3 chunks
105} while (dataAvailable);
106
107console.log("All data processed. Total chunks: " + chunksProcessed);
108// Output: Processing chunk 1, Processing chunk 2, Processing chunk 3, All data processed. Total chunks: 3
109
110// Key differences:
111// - do-while: code runs first, then condition checked
112// - while: condition checked first, then code may run
113// - Use do-while when you need guaranteed first executionControl Statements: Break and Continue in While Loops
The break and continue statements provide precise control over while loop execution. Break exits the loop immediately, while continue skips the current iteration and reevaluates the condition.
1// Break statement in while loops
2console.log("=== BREAK STATEMENT EXAMPLES ===");
3
4// Example 1: Break when target found
5let numbers = [1, 3, 5, 7, 9, 11, 13];
6let index = 0;
7let target = 7;
8
9while (index < numbers.length) {
10 if (numbers[index] === target) {
11 console.log(`Found ${target} at index ${index}`);
12 break; // Exit loop immediately
13 }
14 console.log(`Checking index ${index}: ${numbers[index]}`);
15 index++;
16}
17// Output: Checking index 0: 1, Checking index 1: 3, Checking index 2: 5, Found 7 at index 3
18
19// Example 2: Break with complex condition
20let total = 0;
21let count = 1;
22
23while (count <= 100) {
24 total += count;
25
26 if (total > 50) {
27 console.log(`Total exceeded 50 at count ${count}. Breaking.`);
28 break;
29 }
30
31 console.log(`Count: ${count}, Total: ${total}`);
32 count++;
33}
34// Output: Count: 1, Total: 1 ... until total exceeds 50
35
36// Example 3: Break in nested loops
37let i = 0;
38outer: while (i < 3) {
39 let j = 0;
40 console.log(`Outer loop: i = ${i}`);
41
42 while (j < 3) {
43 if (i === 1 && j === 1) {
44 console.log("Breaking both loops at i=1, j=1");
45 break outer; // Break outer loop with label
46 }
47 console.log(` Inner loop: j = ${j}`);
48 j++;
49 }
50 i++;
51}
52
53// Continue statement in while loops
54console.log("\n=== CONTINUE STATEMENT EXAMPLES ===");
55
56// Example 1: Skip even numbers
57let num = 0;
58while (num < 10) {
59 num++;
60
61 if (num % 2 === 0) {
62 continue; // Skip even numbers
63 }
64
65 console.log("Odd number: " + num);
66}
67// Output: Odd number: 1, Odd number: 3, Odd number: 5, Odd number: 7, Odd number: 9
68
69// Example 2: Skip invalid data
70let data = ["valid", null, "also valid", undefined, "", "valid again"];
71let dataIndex = 0;
72
73while (dataIndex < data.length) {
74 let current = data[dataIndex];
75 dataIndex++;
76
77 // Skip null, undefined, and empty strings
78 if (!current) {
79 console.log(`Skipping invalid data at index ${dataIndex - 1}`);
80 continue;
81 }
82
83 console.log(`Processing: "${current}"`);
84}
85// Output: Processing: "valid", Skipping invalid data..., Processing: "also valid", etc.
86
87// Example 3: Continue with complex skipping logic
88let counter = 0;
89while (counter < 20) {
90 counter++;
91
92 // Skip numbers divisible by 3 or 5
93 if (counter % 3 === 0 || counter % 5 === 0) {
94 continue;
95 }
96
97 console.log(`Number not divisible by 3 or 5: ${counter}`);
98}
99// Output: 1, 2, 4, 7, 8, 11, 13, 14, 16, 17, 19
100
101// Example 4: Practical use case - data processing with conditions
102let users = [
103 { name: "Alice", active: true, role: "admin" },
104 { name: "Bob", active: false, role: "user" },
105 { name: "Charlie", active: true, role: "moderator" },
106 { name: "Diana", active: true, role: "user" }
107];
108
109let userIndex = 0;
110console.log("\nActive non-admin users:");
111
112while (userIndex < users.length) {
113 let user = users[userIndex];
114 userIndex++;
115
116 // Skip inactive users
117 if (!user.active) {
118 continue;
119 }
120
121 // Skip admin users
122 if (user.role === "admin") {
123 continue;
124 }
125
126 console.log(`- ${user.name} (${user.role})`);
127}
128// Output: - Charlie (moderator), - Diana (user)
129
130// Example 5: Break and continue together
131let value = 0;
132while (value < 100) {
133 value++;
134
135 // Skip multiples of 7
136 if (value % 7 === 0) {
137 continue;
138 }
139
140 // Stop if value exceeds 85
141 if (value > 85) {
142 console.log(`Reached ${value}, stopping.`);
143 break;
144 }
145
146 console.log(`Processing value: ${value}`);
147}
148// Processes values 1-85, skipping multiples of 7, stops at 86Practical While Loop Patterns and Use Cases
While loops excel in specific scenarios where the number of iterations is unknown or depends on external factors. Understanding these patterns helps you apply while loops effectively in real-world applications.
1// Pattern 1: User input validation
2let userAge;
3console.log("=== USER INPUT VALIDATION ===");
4
5// Simulate user input validation
6let inputAttempts = 0;
7while (true) { // Infinite loop until valid input
8 inputAttempts++;
9
10 // Simulate getting user input (in real app, this would be prompt or form input)
11 userAge = inputAttempts === 1 ? "abc" : "25"; // First invalid, then valid
12
13 // Convert to number and validate
14 let ageNumber = parseInt(userAge);
15
16 if (isNaN(ageNumber)) {
17 console.log("Invalid input: Please enter a number");
18 continue;
19 }
20
21 if (ageNumber < 0 || ageNumber > 120) {
22 console.log("Invalid age: Please enter age between 0-120");
23 continue;
24 }
25
26 console.log(`Valid age entered: ${ageNumber}`);
27 break; // Exit loop when valid input received
28}
29
30// Pattern 2: Game loop simulation
31console.log("\n=== GAME LOOP SIMULATION ===");
32let gameRunning = true;
33let playerHealth = 100;
34let enemyHealth = 100;
35let round = 1;
36
37while (gameRunning) {
38 console.log(`\n--- Round ${round} ---`);
39 console.log(`Player Health: ${playerHealth}, Enemy Health: ${enemyHealth}`);
40
41 // Simulate combat
42 let playerDamage = Math.floor(Math.random() * 20) + 5;
43 let enemyDamage = Math.floor(Math.random() * 15) + 5;
44
45 enemyHealth -= playerDamage;
46 playerHealth -= enemyDamage;
47
48 console.log(`Player deals ${playerDamage} damage`);
49 console.log(`Enemy deals ${enemyDamage} damage`);
50
51 // Check win conditions
52 if (enemyHealth <= 0) {
53 console.log("🎉 Player wins!");
54 gameRunning = false;
55 } else if (playerHealth <= 0) {
56 console.log("💀 Enemy wins!");
57 gameRunning = false;
58 }
59
60 round++;
61
62 // Safety check - maximum rounds
63 if (round > 10) {
64 console.log("⏰ Time's up! Draw!");
65 gameRunning = false;
66 }
67}
68
69// Pattern 3: Data stream processing
70console.log("\n=== DATA STREAM PROCESSING ===");
71let buffer = ["chunk1", "chunk2", "chunk3", "chunk4", "END"];
72let bufferIndex = 0;
73let processing = true;
74
75while (processing) {
76 let chunk = buffer[bufferIndex];
77 bufferIndex++;
78
79 if (chunk === "END") {
80 console.log("End of stream reached");
81 processing = false;
82 continue;
83 }
84
85 console.log(`Processing chunk: ${chunk}`);
86
87 // Simulate processing time
88 // In real application, this might involve network calls or file operations
89}
90
91// Pattern 4: Retry mechanism with exponential backoff
92console.log("\n=== RETRY MECHANISM ===");
93let maxRetries = 5;
94let retryCount = 0;
95let success = false;
96
97while (!success && retryCount < maxRetries) {
98 retryCount++;
99 console.log(`Attempt ${retryCount}...`);
100
101 // Simulate API call that might fail
102 let apiSuccess = retryCount >= 3; // Succeeds on 3rd attempt
103
104 if (apiSuccess) {
105 console.log("✅ API call successful!");
106 success = true;
107 } else {
108 console.log("❌ API call failed");
109
110 // Exponential backoff: wait longer each retry
111 let waitTime = Math.pow(2, retryCount) * 100; // 200ms, 400ms, 800ms...
112 console.log(`Waiting ${waitTime}ms before retry...`);
113
114 if (retryCount === maxRetries) {
115 console.log("🚫 Max retries reached. Giving up.");
116 }
117 }
118}
119
120// Pattern 5: Polling for condition changes
121console.log("\n=== CONDITION POLLING ===");
122let dataReady = false;
123let pollCount = 0;
124const maxPolls = 10;
125
126// Simulate waiting for external condition (file upload, API response, etc.)
127while (!dataReady && pollCount < maxPolls) {
128 pollCount++;
129 console.log(`Polling attempt ${pollCount}...`);
130
131 // Simulate condition becoming true
132 dataReady = pollCount >= 4; // Data becomes ready on 4th poll
133
134 if (!dataReady) {
135 console.log("Data not ready yet, waiting...");
136 // In real application, this might be setTimeout or async delay
137 } else {
138 console.log("✅ Data is now ready!");
139 }
140}
141
142// Pattern 6: Processing until empty
143console.log("\n=== PROCESS UNTIL EMPTY ===");
144let queue = ["task1", "task2", "task3", "task4"];
145let tasksProcessed = 0;
146
147while (queue.length > 0) {
148 let task = queue.shift(); // Remove first item
149 tasksProcessed++;
150 console.log(`Processing task: ${task} (${tasksProcessed} total)`);
151
152 // Simulate task processing
153 // In real application, this might involve complex operations
154}
155
156console.log(`All ${tasksProcessed} tasks completed!`);
157
158// Pattern 7: Mathematical convergence
159console.log("\n=== MATHEMATICAL CONVERGENCE ===");
160let estimate = 10;
161let previousEstimate = 0;
162let iteration = 0;
163const tolerance = 0.0001;
164
165// Newton's method approximation for square root of 2
166while (Math.abs(estimate - previousEstimate) > tolerance && iteration < 100) {
167 iteration++;
168 previousEstimate = estimate;
169 estimate = (estimate + 2 / estimate) / 2;
170
171 console.log(`Iteration ${iteration}: ${estimate}`);
172}
173
174console.log(`√2 ≈ ${estimate} (converged in ${iteration} iterations)`);Common While Loop Mistakes and Pitfalls
Understanding common mistakes with while loops is crucial for writing robust code. While loops are particularly prone to infinite loops and logical errors if not carefully constructed.
1// Mistake 1: Infinite loops
2// WRONG: Missing increment
3let count = 0;
4// while (count < 5) {
5// console.log("Infinite: " + count);
6// // Forgot count++ - this runs forever!
7// }
8
9// CORRECT: Always update loop variables
10while (count < 5) {
11 console.log("Safe: " + count);
12 count++; // Essential!
13}
14
15// Mistake 2: Condition that never becomes false
16// WRONG: Always true condition
17let flag = true;
18// while (flag) {
19// console.log("This runs forever unless break is used");
20// // No mechanism to set flag to false
21// }
22
23// CORRECT: Ensure condition can become false
24let safeFlag = true;
25let iterations = 0;
26while (safeFlag && iterations < 10) {
27 console.log("Safe iteration: " + iterations);
28 iterations++;
29 if (iterations >= 5) {
30 safeFlag = false; // Condition becomes false
31 }
32}
33
34// Mistake 3: Using assignment (=) instead of comparison (==/===)
35let value = 0;
36
37// WRONG: Assignment in condition (always true)
38// while (value = 5) { // Sets value to 5, which is truthy - infinite loop!
39// console.log("This runs forever");
40// }
41
42// CORRECT: Use comparison operator
43while (value === 5) { // This condition is false, loop doesn't run
44 console.log("This won't run");
45}
46
47// Mistake 4: Not initializing loop variables
48// WRONG: Using undefined variable
49// let uninitialized;
50// while (uninitialized < 10) { // uninitialized is undefined
51// console.log("This causes error or unexpected behavior");
52// }
53
54// CORRECT: Always initialize loop variables
55let initialized = 0;
56while (initialized < 3) {
57 console.log("Initialized: " + initialized);
58 initialized++;
59}
60
61// Mistake 5: Modifying loop variable in unpredictable ways
62let counter = 0;
63
64// WRONG: Unpredictable modification
65// while (counter < 10) {
66// console.log(counter);
67// counter += Math.random() * 3; // Might skip over termination condition
68// }
69
70// CORRECT: Predictable increment
71while (counter < 5) {
72 console.log("Predictable: " + counter);
73 counter++; // Always increases by 1
74}
75
76// Mistake 6: Using floating point numbers in conditions
77// WRONG: Floating point precision issues
78// let decimal = 0.0;
79// while (decimal !== 1.0) { // Might never equal exactly 1.0 due to precision
80// console.log(decimal);
81// decimal += 0.1;
82// }
83
84// CORRECT: Use tolerance for floating point comparisons
85let decimal = 0.0;
86while (Math.abs(decimal - 1.0) > 0.0001 && decimal < 1.1) {
87 console.log("Decimal with tolerance: " + decimal.toFixed(2));
88 decimal += 0.1;
89}
90
91// Mistake 7: Not handling edge cases
92let userInput = "";
93
94// WRONG: No handling for empty or null input
95// while (userInput !== "quit") {
96// // If userInput starts as empty, this might not behave as expected
97// console.log("Processing: " + userInput);
98// userInput = "quit"; // Simulate user input
99// }
100
101// CORRECT: Handle edge cases explicitly
102let input = "";
103while (input !== "quit") {
104 if (input === "") {
105 console.log("Please enter a command");
106 } else {
107 console.log("Processing: " + input);
108 }
109 input = "quit"; // Simulate user input
110}
111
112// Mistake 8: Complex conditions that are hard to debug
113let x = 0, y = 10, z = 5;
114
115// WRONG: Overly complex condition
116// while (x < y && (z > 0 || x % 2 === 0) && !(x === 5 && z === 3)) {
117// console.log(`x=${x}, y=${y}, z=${z}`);
118// x++;
119// z--;
120// }
121
122// CORRECT: Break complex conditions into variables
123let continueLoop = true;
124while (continueLoop) {
125 let condition1 = x < y;
126 let condition2 = z > 0 || x % 2 === 0;
127 let condition3 = !(x === 5 && z === 3);
128
129 continueLoop = condition1 && condition2 && condition3;
130
131 if (continueLoop) {
132 console.log(`x=${x}, y=${y}, z=${z}`);
133 x++;
134 z--;
135 }
136}
137
138// Mistake 9: Not using break for early termination when appropriate
139let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
140let searchIndex = 0;
141let targetValue = 7;
142
143// LESS EFFICIENT: Continues after finding target
144// while (searchIndex < data.length) {
145// if (data[searchIndex] === targetValue) {
146// console.log("Found at index: " + searchIndex);
147// }
148// searchIndex++;
149// }
150
151// MORE EFFICIENT: Break when target found
152while (searchIndex < data.length) {
153 if (data[searchIndex] === targetValue) {
154 console.log("Found at index: " + searchIndex);
155 break; // Stop searching
156 }
157 searchIndex++;
158}
159
160// Mistake 10: Not considering performance with large datasets
161let bigArray = new Array(1000000).fill(0);
162
163// LESS EFFICIENT: Repeated function calls in condition
164// let i = 0;
165// while (i < bigArray.length) { // length checked every iteration
166// bigArray[i] = i;
167// i++;
168// }
169
170// MORE EFFICIENT: Cache length
171let j = 0;
172const arrayLength = bigArray.length;
173while (j < arrayLength) { // Length cached
174 bigArray[j] = j;
175 j++;
176}While Loop Best Practices
Following established best practices for while loops leads to more readable, maintainable, and reliable code. These guidelines help you write effective while loops that are easy to understand and debug.
1// Best Practice 1: Use descriptive variable names
2let retryAttempt = 0;
3const MAX_RETRIES = 3;
4
5// GOOD - descriptive names
6while (retryAttempt < MAX_RETRIES) {
7 console.log(`Retry attempt ${retryAttempt + 1}`);
8 retryAttempt++;
9}
10
11// AVOID - unclear names
12// let x = 0;
13// while (x < 3) {
14// console.log(x);
15// x++;
16// }
17
18// Best Practice 2: Always ensure loop termination
19let iteration = 0;
20const SAFETY_LIMIT = 1000;
21
22// GOOD - safety limit to prevent infinite loops
23while (someCondition && iteration < SAFETY_LIMIT) {
24 // Process data
25 iteration++;
26}
27
28if (iteration >= SAFETY_LIMIT) {
29 console.warn("Loop reached safety limit - check for infinite loop");
30}
31
32// Best Practice 3: Use constants for magic numbers
33const MAX_LOGIN_ATTEMPTS = 5;
34const TIMEOUT_MS = 5000;
35
36let loginAttempts = 0;
37let loginSuccessful = false;
38
39while (loginAttempts < MAX_LOGIN_ATTEMPTS && !loginSuccessful) {
40 console.log(`Login attempt ${loginAttempts + 1}`);
41 // Simulate login logic
42 loginSuccessful = loginAttempts >= 2; // Succeeds on 3rd attempt
43 loginAttempts++;
44}
45
46// Best Practice 4: Keep loop conditions simple and clear
47let shouldProcess = true;
48let itemCount = 0;
49
50// GOOD - simple, clear condition
51while (shouldProcess) {
52 itemCount++;
53 console.log(`Processing item ${itemCount}`);
54
55 // Clear condition to stop
56 shouldProcess = itemCount < 5;
57}
58
59// Best Practice 5: Use break for early termination when appropriate
60let data = [1, 2, 3, -1, 4, 5];
61let dataIndex = 0;
62
63// GOOD - break when condition met
64while (dataIndex < data.length) {
65 if (data[dataIndex] < 0) {
66 console.log("Negative number found, stopping processing");
67 break;
68 }
69 console.log("Processing:", data[dataIndex]);
70 dataIndex++;
71}
72
73// Best Practice 6: Document complex loop logic
74// Process user data until either:
75// - All data processed, OR
76// - Error encountered, OR
77// - Timeout reached
78let processingActive = true;
79let processedItems = 0;
80let errorEncountered = false;
81const MAX_ITEMS = 100;
82const TIMEOUT = 30000; // 30 seconds
83
84while (processingActive) {
85 // Check termination conditions
86 if (processedItems >= MAX_ITEMS) {
87 console.log("Maximum items processed");
88 processingActive = false;
89 continue;
90 }
91
92 if (errorEncountered) {
93 console.log("Error encountered, stopping");
94 processingActive = false;
95 continue;
96 }
97
98 // Process current item
99 console.log(`Processing item ${processedItems + 1}`);
100 processedItems++;
101
102 // Simulate potential error
103 errorEncountered = processedItems === 5;
104}
105
106// Best Practice 7: Consider using for loops when iteration count is known
107// When you know exact iteration count, for loop might be clearer
108
109// While loop version
110let whileCounter = 0;
111while (whileCounter < 5) {
112 console.log("While: " + whileCounter);
113 whileCounter++;
114}
115
116// For loop version (often clearer for fixed iterations)
117for (let forCounter = 0; forCounter < 5; forCounter++) {
118 console.log("For: " + forCounter);
119}
120
121// Best Practice 8: Handle edge cases gracefully
122let userData = null; // Could be null, undefined, or empty
123
124// GOOD - check for edge cases
125if (userData) {
126 let dataIndex = 0;
127 while (dataIndex < userData.length) {
128 console.log("Processing:", userData[dataIndex]);
129 dataIndex++;
130 }
131} else {
132 console.log("No user data to process");
133}
134
135// Best Practice 9: Use appropriate loop type for the scenario
136// Use while loops for:
137// - Unknown iteration count
138// - Event-driven conditions
139// - Waiting for external conditions
140// - Complex termination logic
141
142// Use for loops for:
143// - Known iteration count
144// - Simple numeric sequences
145// - Array iteration
146
147// Best Practice 10: Test both normal and edge cases
148function testWhileLoop() {
149 let testCases = [
150 { input: 0, expected: 0 },
151 { input: 1, expected: 1 },
152 { input: 5, expected: 5 }
153 ];
154
155 for (let testCase of testCases) {
156 let result = 0;
157 let counter = 0;
158
159 while (counter < testCase.input) {
160 result++;
161 counter++;
162 }
163
164 console.assert(result === testCase.expected,
165 `Test failed: input ${testCase.input}, expected ${testCase.expected}, got ${result}`);
166 }
167
168 console.log("All while loop tests passed!");
169}
170
171testWhileLoop();
172
173// Best Practice 11: Use meaningful condition variables
174let isDownloadComplete = false;
175let downloadProgress = 0;
176
177// GOOD - meaningful condition name
178while (!isDownloadComplete) {
179 downloadProgress += 10;
180 console.log(`Download progress: ${downloadProgress}%`);
181
182 isDownloadComplete = downloadProgress >= 100;
183}
184
185// Best Practice 12: Consider extracting complex loop bodies to functions
186function processItem(item) {
187 // Complex processing logic
188 return item * 2;
189}
190
191let items = [1, 2, 3, 4, 5];
192let itemIndex = 0;
193
194while (itemIndex < items.length) {
195 let result = processItem(items[itemIndex]);
196 console.log(`Processed item: ${result}`);
197 itemIndex++;
198}
199
200// Best Practice 13: Use appropriate loop control statements
201let values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
202let valueIndex = 0;
203
204while (valueIndex < values.length) {
205 let value = values[valueIndex];
206 valueIndex++;
207
208 // Skip even numbers
209 if (value % 2 === 0) {
210 continue;
211 }
212
213 // Stop if value exceeds 7
214 if (value > 7) {
215 break;
216 }
217
218 console.log("Processing odd number:", value);
219}