JavaScript Loops Explained — for, while, and forEach with Real Examples
Every app you've ever used relies on loops. When Instagram loads your feed, a loop runs through every post and renders it on screen. When Spotify builds your playlist, a loop processes every song. When a game checks if you've been hit by an enemy, a loop is running dozens of times per second. Loops are not just a feature of JavaScript — they are one of the fundamental building blocks of everything a program does.
The for Loop — When You Know Exactly How Many Times to Repeat
The for loop is the most common loop you'll write. You reach for it when you know upfront how many times something needs to happen — print 5 messages, process 10 orders, light up 7 checkboxes. Think of it like a strict gym trainer who says: 'Do exactly 10 reps, then stop.' No more, no less.
A for loop has three parts packed into one line, separated by semicolons. First, a starting point — you create a counter variable, usually called i, and set it to 0 (because JavaScript lists start counting from 0, not 1). Second, a condition — the loop keeps running as long as this condition is true. Third, an update — after each loop, you change the counter, usually by adding 1.
When the condition becomes false, JavaScript exits the loop and moves on. That's the whole mechanic. Everything else is just variations on this pattern.
// Imagine you're a barista making 5 coffees in a row. // You don't write five separate instructions — you loop. const totalCoffees = 5; for (let coffeeNumber = 1; coffeeNumber <= totalCoffees; coffeeNumber++) { // This block runs once for each coffee // coffeeNumber starts at 1, goes up by 1 each time, stops after 5 console.log(`Making coffee number ${coffeeNumber} of ${totalCoffees}`); } console.log("All coffees done! Time for a break."); // --- // Now let's loop through an actual array of items — a very common real-world use. const studentNames = ["Alice", "Bob", "Carmen", "David"]; for (let index = 0; index < studentNames.length; index++) { // studentNames.length is 4, so index goes 0, 1, 2, 3 // When index reaches 4, the condition (4 < 4) is FALSE, so the loop stops console.log(`Student ${index + 1}: ${studentNames[index]}`); }
Making coffee number 2 of 5
Making coffee number 3 of 5
Making coffee number 4 of 5
Making coffee number 5 of 5
All coffees done! Time for a break.
Student 1: Alice
Student 2: Bob
Student 3: Carmen
Student 4: David
The while Loop — When You Don't Know How Many Times to Repeat
The while loop is what you use when you can't predict upfront how many times you'll need to repeat something. The loop just keeps going as long as a condition stays true, and stops the moment it becomes false.
A great real-world analogy: imagine you're fishing. You don't say 'I'll cast exactly 7 times.' You say 'I'll keep casting until I catch a fish.' You don't know if that's 2 casts or 200. That uncertainty is exactly when while is the right tool.
In code, while loops are common for things like: keep asking the user for a password until they get it right, keep downloading data until the file is complete, or keep running a game loop until the player loses. The key discipline with while loops is that something inside the loop must eventually make the condition false — otherwise you get an infinite loop, and your program freezes forever.
// Scenario: A vending machine keeps accepting coins until you've // inserted enough money for a snack that costs 75 cents. const snackPrice = 75; // in cents let totalInserted = 0; // start with no coins inserted let coinCount = 0; // track how many coins were put in // The condition: keep looping while we haven't paid enough while (totalInserted < snackPrice) { const coinValue = 25; // pretend every coin is a quarter (25 cents) totalInserted += coinValue; // add the coin's value to the running total coinCount++; // count one more coin inserted console.log(`Inserted coin #${coinCount}: total is now ${totalInserted} cents`); } // We only reach this line AFTER the condition (totalInserted < 75) becomes false console.log(`\nYou inserted ${coinCount} coins. Dispensing your snack! Enjoy!`); // --- // Another example: countdown timer let secondsRemaining = 5; while (secondsRemaining > 0) { console.log(`Launching in ${secondsRemaining}...`); secondsRemaining--; // THIS IS CRITICAL — without this, secondsRemaining never changes and we loop forever } console.log("🚀 Liftoff!");
Inserted coin #2: total is now 50 cents
Inserted coin #3: total is now 75 cents
You inserted 3 coins. Dispensing your snack! Enjoy!
Launching in 5...
Launching in 4...
Launching in 3...
Launching in 2...
Launching in 1...
🚀 Liftoff!
forEach and for...of — The Modern, Readable Way to Loop Arrays
Once you understand for loops, JavaScript gives you two cleaner tools specifically designed for looping through arrays and collections: forEach and for...of. They exist because the classic for loop, while powerful, has a lot of visual noise — the counter, the condition, the increment. When all you want to do is 'go through every item in this list,' there's a simpler way.
forEach is a method that lives on every array. You hand it a function, and it calls that function once for each item, automatically passing in the item, its index, and the whole array if you need them. It's expressive — reading it out loud almost sounds like plain English: 'for each order in orders, do this thing.'
for...of is even simpler — it's a loop syntax (like for) but designed for collections. You get the value directly without index gymnastics. Use for...of when you just need the values. Use forEach when you want the built-in index parameter without extra setup. Neither can be 'broken out of' easily with break — use a classic for loop if you need to exit early.
const pizzaOrders = [ { customer: "Marco", topping: "Pepperoni" }, { customer: "Yuki", topping: "Mushrooms" }, { customer: "Priya", topping: "Extra Cheese" }, { customer: "Jordan", topping: "Jalapeños" } ]; // --- forEach --- // The function receives each item in the array, one at a time. // 'order' is just the name we give it — you can name it anything. // 'orderIndex' is automatically provided — it's the position (0, 1, 2...) console.log("=== forEach Example ==="); pizzaOrders.forEach(function(order, orderIndex) { console.log(`Order #${orderIndex + 1}: ${order.customer} wants ${order.topping} pizza`); }); // --- for...of --- // Cleaner syntax when you only need the value, not the index. // It reads almost like plain English: "for each order of pizzaOrders" console.log("\n=== for...of Example ==="); for (const order of pizzaOrders) { // 'order' holds the current item on each iteration console.log(`Preparing ${order.topping} pizza for ${order.customer}`); } // --- Arrow function shorthand (you'll see this everywhere in real codebases) --- console.log("\n=== Arrow Function Shorthand ==="); pizzaOrders.forEach((order) => { console.log(`Ready: ${order.customer}'s ${order.topping} pizza 🍕`); });
Order #1: Marco wants Pepperoni pizza
Order #2: Yuki wants Mushrooms pizza
Order #3: Priya wants Extra Cheese pizza
Order #4: Jordan wants Jalapeños pizza
=== for...of Example ===
Preparing Pepperoni pizza for Marco
Preparing Mushrooms pizza for Yuki
Preparing Extra Cheese pizza for Priya
Preparing Jalapeños pizza for Jordan
=== Arrow Function Shorthand ===
Ready: Marco's Pepperoni pizza 🍕
Ready: Yuki's Mushrooms pizza 🍕
Ready: Priya's Extra Cheese pizza 🍕
Ready: Jordan's Jalapeños pizza 🍕
do...while — The Loop That Always Runs at Least Once
There's one more loop worth knowing: do...while. It's the least common, but it solves a specific problem elegantly. Every other loop checks its condition before running the code block. A do...while checks the condition after. That means the block always executes at least one time, even if the condition starts out false.
When does that matter? Think of a login form. You always want to show the form at least once — you check if the login was successful after the user submits it, not before they've even seen it. Or think of a game's main menu: show it first, then decide whether to keep showing it based on what the player picks.
In practice, do...while is genuinely rare in modern JavaScript. You'll mostly see it in interview questions and legacy code. But understanding it deepens your grasp of how loop conditions work, which makes you sharper with all the other loops too.
// Scenario: A quiz app that always asks at least one question, // then checks if the player wants to continue. // We'll simulate the user's responses with an array const simulatedUserResponses = ["yes", "yes", "no"]; // 'no' means they quit let responseIndex = 0; let questionNumber = 0; do { questionNumber++; // In a real app, this would be an actual quiz question console.log(`Question ${questionNumber}: What is 2 + 2? (Simulated answer: 4)`); // Simulate getting a response from the user const userWantsToContinue = simulatedUserResponses[responseIndex]; responseIndex++; console.log(`Player said: "${userWantsToContinue}"`); // The condition is checked DOWN HERE — after the block already ran if (userWantsToContinue !== "yes") { console.log("\nPlayer chose to stop. Thanks for playing!"); break; // exit the loop } } while (responseIndex < simulatedUserResponses.length); console.log(`Total questions answered: ${questionNumber}`); // Key point: even if simulatedUserResponses was empty and the condition // was false from the start, the block inside 'do' would still run once.
Player said: "yes"
Question 2: What is 2 + 2? (Simulated answer: 4)
Player said: "yes"
Question 3: What is 2 + 2? (Simulated answer: 4)
Player said: "no"
Player chose to stop. Thanks for playing!
Total questions answered: 3
| Loop Type | Best Used When | Checks Condition | Works with break/continue | Readable for Arrays |
|---|---|---|---|---|
| for | You know the exact count upfront | Before each iteration | Yes | Works, but verbose |
| while | Condition depends on unpredictable state | Before each iteration | Yes | Possible, but unusual |
| do...while | Block must run at least once regardless | After each iteration | Yes | Rare in practice |
| forEach | Iterating every item in an array | N/A (array-driven) | No — use for instead | Excellent — most readable |
| for...of | Iterating values in any iterable collection | N/A (collection-driven) | Yes | Excellent — clean syntax |
🎯 Key Takeaways
- Use a for loop when you know exactly how many iterations you need — it's the most precise and flexible loop, and the only one that natively supports breaking out early with break.
- Use a while loop when the number of iterations is unknown and depends on a condition that changes during runtime — but always guarantee that something inside the loop will eventually make the condition false.
- forEach and for...of are the modern, readable choices for array iteration — forEach is ideal when you need the index built in, for...of is cleaner when you only need values; neither supports break, so fall back to for when you need early exit.
- do...while is the only loop guaranteed to execute at least once — it checks its condition after the block runs, making it perfect for 'show first, check after' scenarios like login forms or game menus.
⚠ Common Mistakes to Avoid
- ✕Mistake 1: Off-by-one error with array indexes — Writing index <= array.length instead of index < array.length causes the last iteration to access array[array.length], which is undefined. Arrays are zero-indexed, so a 4-item array has valid indexes 0, 1, 2, 3. Index 4 doesn't exist. Fix: always use strictly less than (<) when iterating arrays with a for loop.
- ✕Mistake 2: Creating an infinite loop by forgetting to update the loop variable — In a while loop like 'while (count < 10)', if you never increment count inside the loop, count stays at its starting value forever, the condition is always true, and your program locks up. Fix: before writing a while loop, identify exactly which variable controls the condition and make sure something inside the loop changes it every iteration.
- ✕Mistake 3: Using forEach and expecting break to work — forEach doesn't support break or continue. If you write a forEach and try to use break to exit early when a condition is met, JavaScript will throw a SyntaxError or simply ignore it. Fix: if you need early exit, switch to a classic for loop or for...of loop, both of which fully support break and continue.
Interview Questions on This Topic
- QWhat is the difference between for...in and for...of in JavaScript, and why should you avoid for...in when iterating arrays?
- QCan you explain what causes an infinite loop and walk me through how you'd debug one in a real codebase?
- QIf forEach and a for loop can both iterate an array, why would you ever choose one over the other? Are there situations where forEach simply cannot be used?
Frequently Asked Questions
What is the most commonly used loop in JavaScript?
The for loop and forEach are the most widely used. In modern JavaScript codebases, forEach (and its relatives map and filter) dominate array iteration because they're readable and expressive. The classic for loop is preferred when you need precise control, like breaking out early or iterating backwards.
What's the difference between for...in and for...of in JavaScript?
for...in iterates over the keys (property names) of an object, while for...of iterates over the values of an iterable like an array or string. Never use for...in on arrays — it can pick up inherited prototype properties and its iteration order isn't guaranteed, which leads to subtle bugs. Use for...of for arrays and for...in for plain objects.
How do I stop a loop early in JavaScript?
Use the break keyword inside a for, while, do...while, or for...of loop to exit immediately when a condition is met. If you want to skip the current iteration and jump to the next one without exiting, use continue instead. Note that forEach does not support break or continue — you must use a classic loop if you need early exit.
Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.