Docs

README

4.3 For Loops

Overview

The for loop is the most common looping structure in JavaScript. It executes a block of code a specified number of times, with built-in control over initialization, condition checking, and iteration updates.


Table of Contents

  1. β€’Basic Syntax
  2. β€’How For Loops Work
  3. β€’Loop Components
  4. β€’Iterating Arrays
  5. β€’Nested Loops
  6. β€’Loop Control: break and continue
  7. β€’Common Patterns
  8. β€’Variations
  9. β€’Performance Considerations
  10. β€’Best Practices

Basic Syntax

for (initialization; condition; update) {
  // code to execute each iteration
}

Simple Example

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

Components Breakdown

ComponentPurposeExample
initializationRuns once before loop startslet i = 0
conditionChecked before each iterationi < 5
updateRuns after each iterationi++

How For Loops Work

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  1. Initialization  β”‚  ◄─── Runs once at start
    β”‚     (let i = 0)     β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚   2. Check          β”‚
    β”‚   Condition         β”‚
    β”‚   (i < 5)           β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
       β”‚               β”‚
    [true]          [false]
       β”‚               β”‚
       β–Ό               β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    Exit Loop
    β”‚ 3. Executeβ”‚
    β”‚ Loop Body β”‚
    β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
          β”‚
    β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚ 4. Updateβ”‚
    β”‚  (i++)   β”‚
    β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
          β”‚
          └───────────────────┐
                              β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ό
               β”‚ Go back to Step 2

Step-by-Step Execution

for (let i = 0; i < 3; i++) {
  console.log(`Iteration ${i}`);
}

// Step 1: Initialize i = 0
// Step 2: Check 0 < 3? Yes
// Step 3: Execute body: log "Iteration 0"
// Step 4: Update i to 1

// Step 2: Check 1 < 3? Yes
// Step 3: Execute body: log "Iteration 1"
// Step 4: Update i to 2

// Step 2: Check 2 < 3? Yes
// Step 3: Execute body: log "Iteration 2"
// Step 4: Update i to 3

// Step 2: Check 3 < 3? No
// Exit loop

Loop Components

Initialization

// Single variable
for (let i = 0; i < 5; i++) {}

// Multiple variables
for (let i = 0, j = 10; i < j; i++, j--) {
  console.log(`i=${i}, j=${j}`);
}
// i=0, j=10
// i=1, j=9
// ... until i >= j

// Using existing variable
let k = 0;
for (; k < 5; k++) {
  console.log(k);
}

Condition

// Simple comparison
for (let i = 0; i < 10; i++) {}

// Complex condition
for (let i = 0; i < 10 && i !== 5; i++) {}

// Function call (evaluated each iteration)
for (let i = 0; i < arr.length; i++) {}

// Omitted condition = infinite loop
for (let i = 0; ; i++) {
  if (i >= 5) break; // Must have break!
}

Update Expression

// Increment by 1
for (let i = 0; i < 10; i++) {}

// Increment by 2
for (let i = 0; i < 10; i += 2) {}
// 0, 2, 4, 6, 8

// Decrement
for (let i = 10; i > 0; i--) {}
// 10, 9, 8, ..., 1

// Multiply
for (let i = 1; i <= 1000; i *= 2) {}
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512

// Multiple updates
for (let i = 0, j = 5; i < j; i++, j--) {}

Iterating Arrays

Basic Array Iteration

const fruits = ['apple', 'banana', 'cherry'];

for (let i = 0; i < fruits.length; i++) {
  console.log(`${i}: ${fruits[i]}`);
}
// 0: apple
// 1: banana
// 2: cherry

Optimized Array Iteration

// Cache the length (slightly faster for large arrays)
const arr = [1, 2, 3, 4, 5];

for (let i = 0, len = arr.length; i < len; i++) {
  console.log(arr[i]);
}

Reverse Iteration

const arr = ['a', 'b', 'c', 'd'];

for (let i = arr.length - 1; i >= 0; i--) {
  console.log(arr[i]);
}
// d, c, b, a

Modifying Array During Iteration

// Doubling values in place
const numbers = [1, 2, 3, 4, 5];

for (let i = 0; i < numbers.length; i++) {
  numbers[i] = numbers[i] * 2;
}
console.log(numbers); // [2, 4, 6, 8, 10]

Nested Loops

// 2D iteration
for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    console.log(`(${i}, ${j})`);
  }
}
// (0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2)

Multiplication Table

for (let i = 1; i <= 5; i++) {
  let row = '';
  for (let j = 1; j <= 5; j++) {
    row += (i * j).toString().padStart(4);
  }
  console.log(row);
}
/*
   1   2   3   4   5
   2   4   6   8  10
   3   6   9  12  15
   4   8  12  16  20
   5  10  15  20  25
*/

2D Array Traversal

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}] = ${matrix[row][col]}`);
  }
}

Loop Control: break and continue

break - Exit Loop Immediately

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

continue - Skip Current Iteration

for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) {
    continue; // Skip even numbers
  }
  console.log(i);
}
// Output: 1, 3, 5, 7, 9

Labeled Statements for Nested Loops

outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break outer; // Breaks out of both loops
    }
    console.log(`(${i}, ${j})`);
  }
}
// (0,0), (0,1), (0,2), (1,0)
// Stops at (1,1)

Common Patterns

Sum of Array

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

for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}
console.log(sum); // 15

Find Element

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' },
];

function findById(arr, id) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].id === id) {
      return arr[i];
    }
  }
  return null;
}

console.log(findById(users, 2)); // { id: 2, name: "Bob" }

Count Occurrences

const text = 'hello world';
let count = 0;

for (let i = 0; i < text.length; i++) {
  if (text[i] === 'l') {
    count++;
  }
}
console.log(count); // 3

Build New Array

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

for (let i = 0; i < numbers.length; i++) {
  squared.push(numbers[i] ** 2);
}
console.log(squared); // [1, 4, 9, 16, 25]

Filter Elements

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evens = [];

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    evens.push(numbers[i]);
  }
}
console.log(evens); // [2, 4, 6, 8, 10]

String Manipulation

const str = 'Hello';
let reversed = '';

for (let i = str.length - 1; i >= 0; i--) {
  reversed += str[i];
}
console.log(reversed); // "olleH"

Variations

Omitting Parts

// Omit initialization
let i = 0;
for (; i < 5; i++) {
  console.log(i);
}

// Omit update
for (let i = 0; i < 5; ) {
  console.log(i);
  i++; // Update inside body
}

// Infinite loop (omit condition)
for (;;) {
  // Must use break to exit!
  break;
}

for...of Loop (Arrays)

const fruits = ['apple', 'banana', 'cherry'];

// Traditional for loop
for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

// for...of (cleaner for iteration)
for (const fruit of fruits) {
  console.log(fruit);
}

for...in Loop (Objects)

const person = { name: 'John', age: 30, city: 'NYC' };

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

Performance Considerations

Cache Array Length

// Slower (length recalculated each iteration)
for (let i = 0; i < largeArray.length; i++) {}

// Faster (length cached)
for (let i = 0, len = largeArray.length; i < len; i++) {}

Avoid Expensive Operations in Condition

// ❌ Bad: DOM query every iteration
for (let i = 0; i < document.querySelectorAll('.item').length; i++) {}

// βœ… Good: Cache the result
const items = document.querySelectorAll('.item');
for (let i = 0; i < items.length; i++) {}

Use Local Variables

// Access array element once per iteration
for (let i = 0; i < items.length; i++) {
  const item = items[i]; // Cache reference
  console.log(item.name, item.value, item.type);
}

Best Practices

1. Use Meaningful Variable Names

// ❌ Confusing
for (let x = 0; x < users.length; x++) {
  console.log(users[x].name);
}

// βœ… Clear (when index is needed)
for (let userIndex = 0; userIndex < users.length; userIndex++) {
  console.log(users[userIndex].name);
}

// βœ… Better: Use for...of when index isn't needed
for (const user of users) {
  console.log(user.name);
}

2. Use let, Not var

// ❌ var has function scope (can cause issues)
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Logs: 3, 3, 3

// βœ… let has block scope
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Logs: 0, 1, 2

3. Keep Loop Body Simple

// ❌ Complex loop body
for (let i = 0; i < data.length; i++) {
  // 50 lines of code...
}

// βœ… Extract to function
for (let i = 0; i < data.length; i++) {
  processItem(data[i]);
}

function processItem(item) {
  // Processing logic here
}

4. Use Array Methods When Appropriate

// For loop
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
  doubled.push(numbers[i] * 2);
}

// Array method (often cleaner)
const doubled = numbers.map((n) => n * 2);

Summary

FeatureDescription
InitializationRuns once before loop
ConditionChecked before each iteration
UpdateRuns after each iteration
breakExits loop immediately
continueSkips to next iteration
LabelsControl nested loops

Common Uses

  • β€’Iterating arrays with index access
  • β€’Counting and accumulating
  • β€’Nested iterations (2D arrays)
  • β€’Building new arrays/strings
  • β€’Finding/filtering elements

Next Steps

  • β€’Practice with the examples in examples.js
  • β€’Complete the exercises in exercises.js
  • β€’Learn about while and do...while loops
  • β€’Explore for...of and for...in loops
README - JavaScript Tutorial | DeepML