🔁 Lesson 6: Loops
Stop repeating yourself — let JavaScript do the repetition for you with loops that process data, count, and iterate.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Write
forloops to repeat code a specific number of times - Use
whileanddo...whileloops for condition-based repetition - Iterate over arrays with
for...of - Iterate over object keys with
for...in - Control loop execution with
breakandcontinue - Avoid common pitfalls like infinite loops and off-by-one errors
Estimated Time: 50 minutes
Project: Build a star-rating display and a simple search filter
📑 In This Lesson
Introduction
Imagine you have an array of 100 products and you need to display each one. Without loops, you'd write 100 nearly identical lines of code. Loops let you write the instruction once and repeat it as many times as needed.
JavaScript gives you several loop types, each suited to different situations. By the end of this lesson, you'll know which one to reach for and why.
The for Loop
The for loop is the most common loop. It's ideal when you know how many times you want to repeat something.
Anatomy of a for Loop
// initialization; condition; update
for (let i = 0; i < 5; i++) {
console.log(`Iteration ${i}`);
}
// Output: 0, 1, 2, 3, 4 (runs 5 times)
| Part | What It Does | Runs When |
|---|---|---|
let i = 0 | Creates the counter variable | Once, before the loop starts |
i < 5 | Checks if the loop should continue | Before each iteration |
i++ | Updates the counter | After each iteration |
Looping Through Arrays by Index
const fruits = ["apple", "banana", "cherry", "date"];
for (let i = 0; i < fruits.length; i++) {
console.log(`${i + 1}. ${fruits[i]}`);
}
// "1. apple"
// "2. banana"
// "3. cherry"
// "4. date"
Counting Backwards
// Countdown from 5 to 1
for (let i = 5; i >= 1; i--) {
console.log(i);
}
console.log("Liftoff! 🚀");
Skipping Values
// Count by 2s
for (let i = 0; i <= 10; i += 2) {
console.log(i); // 0, 2, 4, 6, 8, 10
}
while & do...while
Use while when you don't know in advance how many iterations you need — the loop keeps running as long as the condition is true.
while Loop
let attempts = 0;
let password = "";
while (password !== "secret123") {
attempts++;
// Simulating user input
password = attempts === 3 ? "secret123" : "wrong";
console.log(`Attempt ${attempts}: ${password === "secret123" ? "✅ Correct!" : "❌ Wrong"}`);
}
console.log(`Logged in after ${attempts} attempts.`);
// Attempt 1: ❌ Wrong
// Attempt 2: ❌ Wrong
// Attempt 3: ✅ Correct!
// Logged in after 3 attempts.
do...while Loop
The do...while loop guarantees the body runs at least once because it checks the condition after each iteration.
let number;
do {
number = Math.floor(Math.random() * 10) + 1;
console.log(`Rolled: ${number}`);
} while (number !== 7);
console.log("You rolled a 7! 🎲");
// The loop always runs at least once, then keeps
// going until you roll a 7
💡 for vs. while
Use for when you know how many times to loop (or when iterating over a collection with an index). Use while when the loop depends on a condition that could change unpredictably — like waiting for user input, a random result, or a network response.
for...of — Iterating Arrays
The for...of loop is the cleanest way to iterate over arrays (and other iterables like strings). It gives you the value directly — no index needed.
const colors = ["red", "green", "blue", "purple"];
for (const color of colors) {
console.log(color);
}
// "red"
// "green"
// "blue"
// "purple"
Comparing for vs. for...of
const scores = [95, 87, 72, 100, 68];
// Traditional for — you manage the index yourself
for (let i = 0; i < scores.length; i++) {
console.log(`Score ${i + 1}: ${scores[i]}`);
}
// for...of — cleaner when you don't need the index
for (const score of scores) {
console.log(`Score: ${score}`);
}
Iterating Over Strings
const word = "Hello";
for (const char of word) {
console.log(char);
}
// "H", "e", "l", "l", "o"
When You Need Both Index and Value
const tasks = ["Buy groceries", "Walk the dog", "Write code"];
// Use entries() to get both index and value
for (const [index, task] of tasks.entries()) {
console.log(`${index + 1}. ${task}`);
}
// "1. Buy groceries"
// "2. Walk the dog"
// "3. Write code"
✅ Prefer for...of for Arrays
When you just need the values (no index manipulation), for...of is the modern, readable choice. Use a traditional for loop when you need the index for calculations or when looping backwards.
for...in — Iterating Object Keys
The for...in loop iterates over the keys (property names) of an object. It's designed for objects, not arrays.
const user = {
name: "Ray",
role: "Developer",
level: "Senior",
city: "Henderson"
};
for (const key in user) {
console.log(`${key}: ${user[key]}`);
}
// "name: Ray"
// "role: Developer"
// "level: Senior"
// "city: Henderson"
❌ Don't Use for...in on Arrays
for...in iterates over keys, and for arrays, the keys are string indices ("0", "1", "2"). It can also pick up inherited properties. Always use for...of or a traditional for loop for arrays.
const colors = ["red", "green", "blue"];
// ❌ for...in on arrays — keys are strings!
for (const key in colors) {
console.log(typeof key); // "string" — not a number!
}
// ✅ for...of on arrays — gives you values
for (const color of colors) {
console.log(color); // "red", "green", "blue"
}
| Loop | Best For | Gives You |
|---|---|---|
for | Counting, index-based iteration | Control over start, end, step |
while | Unknown number of iterations | Condition-based looping |
for...of | Arrays, strings, iterables | Values directly |
for...in | Object properties | Keys (property names) |
break & continue
These keywords give you finer control over loop execution.
break — Exit Early
break immediately stops the loop and moves to the code after it.
// Find the first number greater than 50
const numbers = [12, 35, 8, 67, 42, 91, 23];
for (const num of numbers) {
if (num > 50) {
console.log(`Found it: ${num}`);
break; // Stop searching — we found what we need
}
}
// "Found it: 67"
// (doesn't check 42, 91, or 23)
continue — Skip and Move On
continue skips the rest of the current iteration and jumps to the next one.
// Print only even numbers
for (let i = 1; i <= 10; i++) {
if (i % 2 !== 0) {
continue; // Skip odd numbers
}
console.log(i);
}
// 2, 4, 6, 8, 10
Real-World Example: Processing Valid Data
const inputs = ["hello", "", "world", null, "JavaScript", undefined, ""];
for (const input of inputs) {
if (!input) {
continue; // Skip empty strings, null, undefined
}
console.log(`Processing: ${input.toUpperCase()}`);
}
// "Processing: HELLO"
// "Processing: WORLD"
// "Processing: JAVASCRIPT"
Common Pitfalls
1. Infinite Loops
If the condition never becomes false, the loop runs forever and freezes your browser.
// ❌ INFINITE LOOP — i never changes!
// for (let i = 0; i < 10; ) {
// console.log(i); // Prints 0 forever
// }
// ❌ INFINITE LOOP — condition always true!
// let count = 0;
// while (count < 5) {
// console.log(count);
// // Forgot count++!
// }
// ✅ Always make sure the loop can exit
let count = 0;
while (count < 5) {
console.log(count);
count++; // This makes the condition eventually false
}
❌ Browser Freeze Recovery
If you accidentally create an infinite loop and your browser freezes, close the tab (not the whole browser). In Chrome DevTools, you can also press the "Pause" button in the Sources panel to stop script execution.
2. Off-by-One Errors
Starting or ending at the wrong number — the most classic loop bug.
const items = ["a", "b", "c"]; // indices 0, 1, 2
// ❌ Off-by-one: uses <= instead of <
// for (let i = 0; i <= items.length; i++) {
// console.log(items[i]); // Last iteration: items[3] → undefined!
// }
// ✅ Correct: < length (not <=)
for (let i = 0; i < items.length; i++) {
console.log(items[i]); // "a", "b", "c"
}
3. Modifying an Array While Looping
// ❌ Dangerous — removing items shifts indices!
const nums = [1, 2, 3, 4, 5];
// for (let i = 0; i < nums.length; i++) {
// if (nums[i] % 2 === 0) {
// nums.splice(i, 1); // Removes the element, but shifts everything
// }
// }
// ✅ Safer — loop backwards or use filter()
const odds = nums.filter(n => n % 2 !== 0);
console.log(odds); // [1, 3, 5]
Hands-on Exercise
🏋️ Exercise: Star Rating & Search Filter
Objective: Practice different loop types by building two mini-programs.
Part 1: Star Rating Display
// TODO: Write a function that takes a rating (1–5)
// and returns a string of stars
// Example: starRating(3) → "★★★☆☆"
// Example: starRating(5) → "★★★★★"
// Hint: Use a for loop to build the string
// Use "★" for filled stars and "☆" for empty stars
Part 2: Simple Search Filter
// TODO: Given this array of products, find and log
// only the ones that contain the search term
// const products = [
// "Wireless Mouse",
// "USB Keyboard",
// "Wireless Headphones",
// "Monitor Stand",
// "Wireless Charger"
// ];
// const searchTerm = "wireless";
// Expected output:
// "Found: Wireless Mouse"
// "Found: Wireless Headphones"
// "Found: Wireless Charger"
// "3 results found."
// Hint: Use .toLowerCase() on both the product name
// and search term for case-insensitive matching
💡 Hint
Part 1: Use a for loop from 1 to 5. Inside the loop, use the ternary operator: i <= rating ? "★" : "☆". Append each star to a result string.
Part 2: Use for...of to iterate the products array. Use .toLowerCase().includes() to check if the product name contains the search term. Keep a counter for the number of matches.
✅ Solution
// Part 1: Star Rating Display
function starRating(rating) {
let stars = "";
for (let i = 1; i <= 5; i++) {
stars += i <= rating ? "★" : "☆";
}
return stars;
}
console.log(starRating(1)); // "★☆☆☆☆"
console.log(starRating(3)); // "★★★☆☆"
console.log(starRating(5)); // "★★★★★"
// Part 2: Simple Search Filter
const products = [
"Wireless Mouse",
"USB Keyboard",
"Wireless Headphones",
"Monitor Stand",
"Wireless Charger"
];
const searchTerm = "wireless";
let matchCount = 0;
for (const product of products) {
if (product.toLowerCase().includes(searchTerm.toLowerCase())) {
console.log(`Found: ${product}`);
matchCount++;
}
}
console.log(`${matchCount} result${matchCount === 1 ? "" : "s"} found.`);
🎯 Quick Quiz
Question 1: How many times does this loop run?
for (let i = 0; i < 3; i++) {
console.log(i);
}
Question 2: Which loop should you use to iterate over an array's values?
Question 3: What does continue do inside a loop?
Summary
🎉 Key Takeaways
for— best when you know how many iterations you need or need index controlwhile— best when the number of iterations depends on a changing conditiondo...while— guarantees at least one iterationfor...of— cleanest way to iterate over arrays and strings (gives values)for...in— iterates over object keys (don't use on arrays)breakexits a loop early;continueskips to the next iteration- Watch out for infinite loops and off-by-one errors
📚 Additional Resources
🚀 What's Next?
You can now make decisions and repeat actions. Next, you'll learn to package reusable logic into functions — the building blocks that keep your code organized, DRY, and powerful.