JavaScript Loops

Classic FOR Loop

// Syntax: for (initialization; condition; increment)
for (let i = 0; i < 5; i++) {
    console.log(`Iteration number: ${i}`);
}

// Practical example: calculate the sum of numbers from 1 to 10
let sum = 0;
for (let i = 1; i <= 10; i++) {
    sum += i;
}
console.log(`Sum from 1 to 10: ${sum}`); // 55

// Iterate through an array with for
let fruits = ["apple", "banana", "orange"];
for (let i = 0; i < fruits.length; i++) {
    console.log(`Fruit ${i + 1}: ${fruits[i]}`);
}

WHILE Loop

// while: repeats AS LONG AS the condition is true
// The condition is checked BEFORE each iteration

let counter = 0;
while (counter < 3) {
    console.log(`While counter: ${counter}`);
    counter++; // IMPORTANT: don't forget to increment!
}

// Practical example: generate random numbers until you get 6
let randomNumber;
let attempts = 0;
while (randomNumber !== 6) {
    randomNumber = Math.floor(Math.random() * 10) + 1;
    attempts++;
    console.log(`Attempt ${attempts}: ${randomNumber}`);
}
console.log(`Found 6 in ${attempts} attempts!`);

// WARNING: avoid infinite loops!
// This loop will never stop
// while (true) {
//     console.log("Infinite loop - DANGER!");
// }

DO...WHILE Loop

// do...while: executes the code AT LEAST ONCE, then checks the condition
// The condition is checked AFTER each iteration

let number = 0;
do {
    console.log(`Do-while: ${number}`);
    number++;
} while (number < 3);

// Practical example: request confirmation (simulation)
let answer;
let attempt = 0;
do {
    attempt++;
    answer = attempt <= 2 ? "no" : "yes"; // Simulation: says "yes" on the 3rd attempt
    console.log(`Attempt ${attempt}: Do you want to continue? ${answer}`);
} while (answer !== "yes" && attempt < 5);

BREAK and CONTINUE

// break: exits the loop completely
console.log("--- Example with BREAK ---");
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        console.log("Break at i = 5");
        break; // Exits the loop
    }
    console.log(`i = ${i}`);
}
// Result: displays from 0 to 4, then stops

// continue: skips to the next iteration
console.log("--- Example with CONTINUE ---");
for (let i = 0; i < 5; i++) {
    if (i === 2) {
        console.log("Continue: we skip i = 2");
        continue; // Skips to i = 3
    }
    console.log(`i = ${i}`);
}
// Result: displays 0, 1, skips 2, then 3, 4

// Practical example: filter even numbers
console.log("--- Display only odd numbers ---");
for (let i = 1; i <= 10; i++) {
    if (i % 2 === 0) {
        continue; // Skip even numbers
    }
    console.log(`Odd number: ${i}`);
}

Labels

// Labels allow you to control nested loops
// Syntax: labelName: for/while...

outerLoop: for (let i = 0; i < 3; i++) {
    console.log(`Outer loop i = ${i}`);
    
    for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) {
            console.log("Break to outerLoop");
            break outerLoop; // Exits BOTH loops
        }
        console.log(`  Inner loop j = ${j}`);
    }
}

// Example with continue and label
search: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 0) {
            console.log("Continue to search");
            continue search; // Skips to i = 2
        }
        console.log(`i=${i}, j=${j}`);
    }
}

FOR...IN Loop

// for...in: iterates through the PROPERTIES of an object (the keys)
// Useful for objects, not recommended for arrays

let person = {
    name: "Marie",
    age: 30,
    city: "Paris"
};

for (let property in person) {
    console.log(`${property}: ${person[property]}`);
}
// Result: name: Marie, age: 30, city: Paris

// Example with an array (generally to be avoided)
let colors = ["red", "green", "blue"];
colors.customProperty = "added";

console.log("--- for...in with array (careful!) ---");
for (let index in colors) {
    console.log(`${index}: ${colors[index]}`);
}
// Also displays the custom property! That's why we avoid for...in with arrays

FOR...OF Loop

// for...of: iterates through the VALUES of iterable objects
// Recommended for arrays, strings, Map, Set...

console.log("--- for...of with array ---");
let animals = ["cat", "dog", "bird"];
for (let animal of animals) {
    console.log(`Animal: ${animal}`);
}

console.log("--- for...of with string ---");
let word = "Hello";
for (let letter of word) {
    console.log(`Letter: ${letter}`);
}

// Comparison for...in vs for...of
console.log("--- Comparison for...in vs for...of ---");
let numbers = [10, 20, 30];

console.log("for...in (indices):");
for (let index in numbers) {
    console.log(index); // Displays: 0, 1, 2
}

console.log("for...of (values):");
for (let value of numbers) {
    console.log(value); // Displays: 10, 20, 30
}

Destructuring in Loops

// We can use destructuring with for...of
let users = [
    {name: "Alice", age: 25},
    {name: "Bob", age: 30},
    {name: "Claire", age: 28}
];

for (let {name, age} of users) {
    console.log(`${name} is ${age} years old`);
}

// With Object.entries() to iterate through an object with for...of
let product = {name: "Laptop", price: 999, stock: 5};
for (let [key, value] of Object.entries(product)) {
    console.log(`${key}: ${value}`);
}

Best Practices

// 1. Use for...of to iterate through arrays
let scores = [85, 92, 78, 96];
for (let score of scores) {
    console.log(`Score: ${score}`);
}

// 2. Use for...in to iterate through objects
let config = {theme: "dark", language: "fr", notifications: true};
for (let option in config) {
    console.log(`${option}: ${config[option]}`);
}

// 3. Prefer the classic for loop when you need the index
for (let i = 0; i < scores.length; i++) {
    console.log(`Score ${i + 1}: ${scores[i]}`);
}

// 4. Use while when you don't know the number of iterations
let value = 1;
while (value < 100) {
    value *= 2;
    console.log(`Doubled value: ${value}`);
}