๐ฏ When to Use Each Loop
for loop โ When you need to count or index (rendering numbered items, accessing array positions)
while loop โ When you don't know how many iterations you need (reading end of file, waiting for user input)
do...while loop โ When the loop must run at least once (menu systems, input validation)
for...of loop โ When iterating over array values (displaying list items, processing data records)
for...in loop โ When iterating over object properties (displaying user profile fields, config settings)
forEach() โ When you need to perform an action on each item (logging, DOM manipulation)
map() โ When transforming each item into a new value (formatting prices, converting data)
filter() โ When selecting items that meet criteria (search results, showing active users)
reduce() โ When combining all items into one value (calculating totals, building objects from arrays)
๐ข Basic for Loop
- Classic counter-based loop โ most flexible option
- Consists of three parts: initialization, condition, increment
- Perfect when you know exactly how many times to loop
- Use
break to exit early if needed
- Use
continue to skip to the next iteration
for (let i = 0; i < 5; i++) {
console.log(i);
}
for (let i = 0; i < 10; i++) {
if (i === 5) break;
console.log(i);
}
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
console.log(i);
}
๐ while Loop
- Runs while condition is true โ checks before each iteration
- Best when you don't know the number of iterations in advance
- Condition is evaluated before the loop body runs
- Always ensure the condition eventually becomes false
- Be careful to avoid infinite loops
let n = 0;
while (n < 3) {
console.log(n);
n++;
}
let count = 0;
while (true) {
console.log(count);
count++;
if (count === 3) break;
}
๐ do...while Loop
- Runs at least once โ checks condition after the loop body
- Useful when you need guaranteed first execution
- The loop body always executes before testing the condition
- Common for user input validation
- Less common than
while but has specific use cases
let i = 0;
do {
console.log(i);
i++;
} while (i < 3);
let userInput;
do {
userInput = prompt("Enter 'yes' to continue:");
} while (userInput !== 'yes');
๐งญ for...of Loop (Iterables)
- Modern loop for arrays and iterables โ cleanest syntax
- Works with arrays, strings, Maps, Sets, and more
- Gives you the value directly (not the index)
- Cannot access the index without additional work
- Best choice for simple array iteration
- More readable than traditional
for loops
const nums = [10, 20, 30];
for (const n of nums) {
console.log(n);
}
for (const char of "Hi") {
console.log(char);
}
const users = [
{ name: 'Ada' },
{ name: 'Bob' }
];
for (const user of users) {
console.log(user.name);
}
๐งฑ for...in Loop (Objects)
- Loops through object keys โ made for objects
- Iterates over all enumerable properties
- Returns the property name (key), not the value
- Use bracket notation to access values:
obj[key]
- Avoid using on arrays (use
for...of instead)
- Order is not guaranteed in all JavaScript engines
const user = {
name: 'Ada',
age: 30,
role: 'developer'
};
for (const key in user) {
console.log(`${key}: ${user[key]}`);
}
๐งฉ Array Loop Methods
- Functional programming approach โ cleaner for transformations
forEach() โ execute a function for each item (no return value)
map() โ transform each item and return a new array
filter() โ create new array with items that pass a test
reduce() โ combine all items into a single value
- These methods don't modify the original array (except
forEach can if you mutate)
- More expressive and less error-prone than manual loops
[1, 2, 3].forEach(n => console.log(n));
const doubled = [1, 2, 3].map(n => n * 2);
const evens = [1, 2, 3, 4].filter(n => n % 2 === 0);
const sum = [1, 2, 3].reduce((total, n) => total + n, 0);
const result = [1, 2, 3, 4]
.filter(n => n > 1)
.map(n => n * 2)
.reduce((a, b) => a + b, 0);
โ๏ธ Loop Control
continue โ skip the current iteration and move to the next
break โ exit the entire loop immediately
- Both work with
for, while, and do...while loops
- Don't work inside
forEach(), map(), etc. (use return instead)
- Use labels to break out of nested loops
- Helps avoid unnecessary iterations
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
console.log(i);
}
for (let i = 0; i < 5; i++) {
if (i === 3) break;
console.log(i);
}
const numbers = [5, 10, 15, 20];
for (const num of numbers) {
if (num === 15) {
console.log('Found it!');
break;
}
}
๐งต Nested Loops
- Loop inside another loop โ for multidimensional data
- Each outer iteration runs the entire inner loop
- Be aware of performance (loops multiply)
- Useful for matrices, grids, and combinations
- Can use labeled
break to exit multiple levels
- Consider if there's a simpler approach first
for (let i = 1; i <= 2; i++) {
for (let j = 1; j <= 3; j++) {
console.log(`i=${i}, j=${j}`);
}
}
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}`);
}
}
const grid = [
[1, 2, 3],
[4, 5, 6]
];
for (const row of grid) {
for (const cell of row) {
console.log(cell);
}
}
โฑ๏ธ Best Practices & Tips
- Prefer
for...of for simple array iteration โ cleanest syntax
- Use array methods (
map, filter, reduce) for data transformations
- Avoid modifying arrays while looping over them (causes bugs)
- Cache array length in performance-critical
for loops
- Use meaningful variable names (
user not i when appropriate)
- Always ensure loops can exit โ watch for infinite loops
- Choose the right tool โ match the loop to your use case
const items = [1, 2, 3, 4];
for (let i = 0; i < items.length; i++) {
items.splice(i, 1);
}
const items = [1, 2, 3, 4];
const filtered = items.filter(n => n > 2);
const users = ['Ada', 'Bob'];
for (const user of users) {
console.log(user);
}
const prices = [10, 20, 30];
const withTax = prices.map(p => p * 1.1);
const user = users.find(u => u.id === 5);
const allAdults = users.every(u => u.age >= 18);