Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →
18 minLesson 6 of 35
JavaScript Fundamentals

Loops: for, while, forEach, for...of

Loops: for, while, forEach, for...of

Loops repeat code until a condition is met. JavaScript has more loop types than most languages — each suited for a different situation. Choosing the right one makes your code more readable and often faster.

The Classic for Loop

// for (initialization; condition; update)
for (let i = 0; i < 5; i++) {
    console.log(i);  // 0, 1, 2, 3, 4
}

// Counting down
for (let i = 10; i > 0; i--) {
    console.log(i);  // 10, 9, 8 ... 1
}

// Iterating arrays by index
const fruits = ["apple", "banana", "cherry"];
for (let i = 0; i < fruits.length; i++) {
    console.log(`${i}: ${fruits[i]}`);
}

// Nested loops — matrix operations
const matrix = [[1,2,3],[4,5,6],[7,8,9]];
for (let row = 0; row < matrix.length; row++) {
    for (let col = 0; col < matrix[row].length; col++) {
        console.log(matrix[row][col]);
    }
}

while Loop

Use while when you don't know upfront how many iterations you need:

// Basic while
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

// Waiting for user input (in Node.js CLI)
let attempts = 0;
while (attempts < 3) {
    const guess = getGuess();
    if (guess === secretNumber) {
        console.log("Correct!");
        break;
    }
    attempts++;
}

// Polling pattern
async function waitForData() {
    let data = null;
    while (!data) {
        data = await fetchData();
        if (!data) await sleep(1000);  // Wait before retrying
    }
    return data;
}

do...while Loop

Executes the body at least once, then checks the condition:

let input;
do {
    input = prompt("Enter a number between 1 and 10:");
} while (input < 1 || input > 10);

// Useful for: menus, retry logic, first-run scenarios
let retries = 0;
do {
    success = attemptConnection();
    retries++;
} while (!success && retries < 3);

for...of Loop

The modern way to iterate over any iterable (arrays, strings, Maps, Sets):

const colors = ["red", "green", "blue"];

for (const color of colors) {
    console.log(color);  // no index needed
}

// Strings are iterable
for (const char of "hello") {
    console.log(char);  // h, e, l, l, o
}

// With index using entries()
for (const [index, value] of colors.entries()) {
    console.log(`${index}: ${value}`);
}

// Maps
const scores = new Map([["Alice", 95], ["Bob", 87]]);
for (const [name, score] of scores) {
    console.log(`${name}: ${score}`);
}

// Sets
const uniqueIds = new Set([1, 2, 3, 2, 1]);
for (const id of uniqueIds) {
    console.log(id);  // 1, 2, 3
}

for...in Loop

Iterates over the enumerable property keys of an object. Avoid using it on arrays:

const person = { name: "Alice", age: 30, city: "NYC" };

for (const key in person) {
    console.log(`${key}: ${person[key]}`);
}
// name: Alice
// age: 30
// city: NYC

// Warning: for...in on arrays includes prototype properties
// Use for...of or forEach for arrays instead

Array Methods: forEach, map, filter, reduce

These are not traditional loops but they process arrays declaratively:

const numbers = [1, 2, 3, 4, 5];

// forEach — run a function for each element, no return value
numbers.forEach((num, index) => {
    console.log(`${index}: ${num}`);
});

// map — transform each element into a new array
const doubled = numbers.map(n => n * 2);  // [2, 4, 6, 8, 10]

// filter — keep elements that pass the test
const evens = numbers.filter(n => n % 2 === 0);  // [2, 4]

// reduce — accumulate to a single value
const sum = numbers.reduce((total, n) => total + n, 0);  // 15

// Chaining
const result = numbers
    .filter(n => n > 2)       // [3, 4, 5]
    .map(n => n ** 2)         // [9, 16, 25]
    .reduce((sum, n) => sum + n, 0);  // 50

break and continue

// break — exit the loop immediately
for (let i = 0; i < 10; i++) {
    if (i === 5) break;
    console.log(i);  // 0, 1, 2, 3, 4
}

// continue — skip current iteration, continue loop
for (let i = 0; i < 10; i++) {
    if (i % 2 === 0) continue;
    console.log(i);  // 1, 3, 5, 7, 9
}

// Labels — break out of nested loops (use sparingly)
outer: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (j === 1) break outer;
        console.log(i, j);
    }
}
// 0 0  ← stops when j hits 1 in first outer iteration

Performance: Which Loop Is Fastest?

For raw speed on large arrays: for > for...of > forEach > map/filter.

const arr = new Array(1_000_000).fill(1);

// Fastest for pure iteration
for (let i = 0; i < arr.length; i++) { /* */ }

// More readable, slightly slower
for (const item of arr) { /* */ }

// Slowest but declarative — preferred for most cases
arr.forEach(item => { /* */ });

In practice, the difference only matters for hot loops processing millions of items. Write readable code first and optimize only when profiling shows a bottleneck.

Common Patterns

// Loop with index + value
fruits.forEach((fruit, i) => console.log(`${i + 1}. ${fruit}`));

// Build an array of results
const squares = Array.from({length: 10}, (_, i) => (i + 1) ** 2);
// [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

// Find first match (stops early)
const target = users.find(u => u.id === 42);

// Check if any/all match
const hasAdmin = users.some(u => u.role === "admin");
const allActive = users.every(u => u.isActive);

// Async iteration (await inside loop)
for (const userId of userIds) {
    const user = await fetchUser(userId);  // works! sequential
    console.log(user.name);
}

// Parallel async (all at once — much faster)
const users = await Promise.all(userIds.map(id => fetchUser(id)));

Next lesson: Functions — declarations, expressions, arrow functions, and the critical difference between them.

📱

Get this course's notes on Telegram!

Free cheat sheets, summaries & practice exercises

Get Notes Free →
!