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​