Skip to main content

Module 4: Loops & Iteration

This module covers all types of loops in JavaScript, teaching you how to repeat code execution efficiently and elegantly.


1. for Loop

The most common loop for known number of iterations.

Basic Syntax

for (initialization; condition; increment) {
// Code to execute
}

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

Common Patterns

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

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

// Multiple variables
for (let i = 0, j = 10; i < j; i++, j--) {
console.log(i, j);
}

Iterating Arrays

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

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

// Reverse iteration
for (let i = colors.length - 1; i >= 0; i--) {
console.log(colors[i]);
}
Performance Tip

Cache array length if accessing it multiple times:

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

2. while Loop

Best for unknown number of iterations.

while (condition) {
// Code to execute
}

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

Practical Examples

// User input validation
let password = '';
while (password.length < 8) {
password = prompt('Enter password (min 8 chars)');
}

// Process until condition
let data = fetchData();
while (data.hasNext()) {
processItem(data.next());
}
Infinite Loops

Always ensure the condition will eventually become false!

// ❌ Infinite loop
while (true) {
console.log('Forever');
}

3. do-while Loop

Executes at least once before checking condition.

do {
// Code to execute
} while (condition);

// Example
let input;
do {
input = prompt('Enter a number greater than 10');
} while (input <= 10);

while vs do-while

// while - might not execute at all
let i = 10;
while (i < 5) {
console.log(i); // Never executes
}

// do-while - executes at least once
let j = 10;
do {
console.log(j); // Executes once
} while (j < 5);

4. for...of Loop (ES6)

Best for iterating arrays and iterables.

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

for (const color of colors) {
console.log(color);
}

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

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

With Index

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

for (const [index, color] of colors.entries()) {
console.log(index, color);
}
Modern Best Practice

Prefer for...of over traditional for loop for arrays when you don't need the index.


5. for...in Loop

For iterating object properties (use with caution).

const user = {
name: 'John',
age: 30,
city: 'New York'
};

for (const key in user) {
console.log(key, user[key]);
}
// Output:
// name John
// age 30
// city New York
Avoid for Arrays

for...in iterates over all enumerable properties, including inherited ones.

// Bad
const arr = [1, 2, 3];
for (const index in arr) {
console.log(arr[index]); // Works but not recommended
}

// Good
for (const value of arr) {
console.log(value);
}

Safe Usage with hasOwnProperty

for (const key in user) {
if (user.hasOwnProperty(key)) {
console.log(key, user[key]);
}
}

// Modern alternative
for (const key of Object.keys(user)) {
console.log(key, user[key]);
}

6. Array Iteration Methods

Modern JavaScript provides better alternatives to loops.

6.1 forEach()

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

numbers.forEach((num, index) => {
console.log(index, num);
});

// Cannot break or continue
// No return value

6.2 map()

Transforms each element and returns new array.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
// [2, 4, 6, 8, 10]

const names = ['john', 'jane'];
const capitalized = names.map(name => name.toUpperCase());
// ['JOHN', 'JANE']

6.3 filter()

Filters elements based on condition.

const numbers = [1, 2, 3, 4, 5, 6];
const evens = numbers.filter(num => num % 2 === 0);
// [2, 4, 6]

const users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 17 },
{ name: 'Bob', age: 30 }
];
const adults = users.filter(user => user.age >= 18);

6.4 reduce()

Reduces array to single value.

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
// 15

const max = numbers.reduce((max, num) => num > max ? num : max);
// 5

// Grouping
const users = [
{ name: 'John', role: 'admin' },
{ name: 'Jane', role: 'user' },
{ name: 'Bob', role: 'admin' }
];

const byRole = users.reduce((acc, user) => {
acc[user.role] = acc[user.role] || [];
acc[user.role].push(user.name);
return acc;
}, {});
// { admin: ['John', 'Bob'], user: ['Jane'] }

6.5 find() & findIndex()

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

const user = users.find(u => u.id === 2);
// { id: 2, name: 'Jane' }

const index = users.findIndex(u => u.id === 2);
// 1

6.6 some() & every()

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

// some: at least one matches
numbers.some(num => num > 3); // true

// every: all match
numbers.every(num => num > 0); // true
numbers.every(num => num > 3); // false

7. Loop Control Statements

7.1 break

Exits the loop completely.

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

// Find first match
const numbers = [1, 5, 8, 12, 15];
let found;
for (const num of numbers) {
if (num > 10) {
found = num;
break;
}
}

7.2 continue

Skips to next iteration.

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

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

break and continue don't work with forEach(). Use for...of or traditional for if needed.


8. Nested Loops

// Multiplication table
for (let i = 1; i <= 5; i++) {
for (let j = 1; j <= 5; j++) {
console.log(`${i} × ${j} = ${i * j}`);
}
}

// 2D array
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

for (const row of matrix) {
for (const cell of row) {
console.log(cell);
}
}

// Breaking out of nested loops
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) break outer;
console.log(i, j);
}
}
Performance

Nested loops can be expensive. Consider time complexity (O(n²), O(n³), etc.).


9. Choosing the Right Loop

Use CaseRecommended Loop
Iterate array valuesfor...of or forEach()
Transform arraymap()
Filter arrayfilter()
Aggregate valuesreduce()
Known iterationsfor
Unknown iterationswhile
At least one iterationdo-while
Object propertiesObject.keys() + for...of
Break/continue neededfor, for...of, while

10. Best Practices

10.1 Prefer Functional Methods

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

// Functional approach
const doubled = numbers.map(num => num * 2);

10.2 Avoid Modifying Loop Variable

// Bad
for (let i = 0; i < 10; i++) {
i += 2; // Confusing
}

// Good
for (let i = 0; i < 10; i += 3) {
// Clear step
}

10.3 Keep Loop Bodies Small

// Bad
for (const user of users) {
// 50 lines of code
}

// Good
for (const user of users) {
processUser(user);
}

function processUser(user) {
// Complex logic here
}

10.4 Don't Optimize Prematurely

// Readable
for (const item of items) {
processItem(item);
}

// "Optimized" but less readable
const len = items.length;
for (let i = 0; i < len; ++i) {
processItem(items[i]);
}
Rule of Thumb

Write readable code first. Optimize only if profiling shows it's a bottleneck.


11. Performance Considerations

// Cache array length (minor optimization)
for (let i = 0, len = arr.length; i < len; i++) {
// process
}

// Reverse loop (slightly faster in some engines)
for (let i = arr.length - 1; i >= 0; i--) {
// process
}

// Avoid function calls in condition
// Bad
for (let i = 0; i < getLength(); i++) {}

// Good
const length = getLength();
for (let i = 0; i < length; i++) {}

Summary

In this module, you learned:

  • ✅ All loop types: for, while, do-while, for...of, for...in
  • ✅ Array iteration methods: forEach, map, filter, reduce
  • ✅ Loop control: break and continue
  • ✅ When to use each loop type
  • ✅ Best practices for clean, efficient loops
  • ✅ Performance considerations
Next Steps

In Module 5, you'll learn about Functions – the building blocks of reusable code.


Practice Exercises

  1. Print numbers 1-100, "Fizz" for multiples of 3, "Buzz" for 5, "FizzBuzz" for both
  2. Calculate sum of all numbers in an array
  3. Find the largest number in an array
  4. Reverse a string using a loop
  5. Create a function to filter even numbers from an array
  6. Use reduce() to count occurrences of each word in a string
  7. Flatten a 2D array using nested loops
  8. Implement a simple search function with break

Additional Resources