Loops
Table of Contents
Loops let you repeat code without writing it over and over. Whether you’re processing every item in an array, waiting for a condition to change, or generating a sequence of values, loops are the tool for the job.
JavaScript has several loop types, each suited to different situations. This tutorial covers all of them with practical examples.
The for Loop
The classic for loop gives you full control over initialization, condition, and increment:
for (let i = 0; i < 5; i++) {
console.log(i);
}
// 0, 1, 2, 3, 4
The three parts:
- Initialization (
let i = 0) — runs once before the loop starts - Condition (
i < 5) — checked before each iteration; loop stops when false - Update (
i++) — runs after each iteration
Counting backwards
for (let i = 10; i > 0; i--) {
console.log(i);
}
// 10, 9, 8, ... 1
Skipping values
// Print even numbers from 0 to 20
for (let i = 0; i <= 20; i += 2) {
console.log(i);
}
// 0, 2, 4, 6, ... 20
Looping through an array by index
const fruits = ["apple", "banana", "cherry"];
for (let i = 0; i < fruits.length; i++) {
console.log(`${i}: ${fruits[i]}`);
}
// 0: apple
// 1: banana
// 2: cherry
The while Loop
Use while when you don’t know how many iterations you need — you just have a condition:
let attempts = 0;
let success = false;
while (!success) {
attempts++;
// Simulate a 30% chance of success
success = Math.random() < 0.3;
}
console.log(`Succeeded after ${attempts} attempts`);
while loops — if the condition never becomes false, you get an infinite loop that freezes your program. Always make sure something inside the loop changes the condition.
The do…while Loop
Like while, but the body runs at least once before checking the condition:
let input;
do {
input = prompt("Enter a number greater than 10:");
} while (input <= 10);
console.log(`You entered: ${input}`);
This is useful when you need to execute the logic before you can evaluate whether to continue.
for…of (Iterating Values)
for...of is the cleanest way to loop through arrays, strings, Maps, Sets, and other iterables:
const colors = ["red", "green", "blue"];
for (const color of colors) {
console.log(color);
}
// red, green, blue
// Works with strings too
for (const char of "hello") {
console.log(char);
}
// h, e, l, l, o
If you need the index alongside the value, use entries():
const tasks = ["Write code", "Run tests", "Deploy"];
for (const [index, task] of tasks.entries()) {
console.log(`${index + 1}. ${task}`);
}
// 1. Write code
// 2. Run tests
// 3. Deploy
for…in (Iterating Object Keys)
for...in loops over an object’s enumerable property names:
const user = {
name: "Alice",
age: 28,
role: "developer"
};
for (const key in user) {
console.log(`${key}: ${user[key]}`);
}
// name: Alice
// age: 28
// role: developer
for...in on arrays. It iterates over property names (which are string indices), and it can include inherited properties. Use for...of for arrays instead.
break and continue
break — exit the loop entirely
const numbers = [1, 3, 7, 12, 5, 22, 8];
// Find the first number greater than 10
let found;
for (const num of numbers) {
if (num > 10) {
found = num;
break; // stop searching
}
}
console.log(found); // 12
continue — skip to the next iteration
const numbers = [1, -2, 3, -4, 5, -6];
// Sum only positive numbers
let sum = 0;
for (const num of numbers) {
if (num < 0) continue; // skip negatives
sum += num;
}
console.log(sum); // 9
Nested Loops
Loops inside loops — useful for grids, matrices, and combinations:
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (const row of matrix) {
for (const cell of row) {
process.stdout.write(`${cell} `);
}
console.log(); // newline after each row
}
// 1 2 3
// 4 5 6
// 7 8 9
Labeled breaks (for exiting nested loops)
const grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
let target = 5;
let found = false;
outer:
for (let row = 0; row < grid.length; row++) {
for (let col = 0; col < grid[row].length; col++) {
if (grid[row][col] === target) {
console.log(`Found ${target} at [${row}][${col}]`);
found = true;
break outer; // exits both loops
}
}
}
Array Methods vs Loops
For arrays, you’ll often use methods like forEach, map, filter, and reduce instead of manual loops. These are covered in the Arrays tutorial, but here’s a quick comparison:
const prices = [10, 25, 5, 40, 15];
// Loop approach
const expensive = [];
for (const price of prices) {
if (price > 20) {
expensive.push(price);
}
}
// Array method approach (preferred for transformations)
const expensiveAlt = prices.filter(price => price > 20);
// Both give: [25, 40]
When to use loops over array methods:
- You need
breakorcontinue(array methods always process every element) - You’re doing something with side effects (DOM updates, API calls)
- Performance matters and you want to avoid creating intermediate arrays
When to use array methods:
- Transforming data (map, filter, reduce)
- You want concise, readable code
- You’re chaining multiple operations
Common Patterns
Building a string
function repeat(str, times) {
let result = "";
for (let i = 0; i < times; i++) {
result += str;
}
return result;
}
console.log(repeat("ha", 3)); // "hahaha"
Finding duplicates
function findDuplicates(arr) {
const seen = new Set();
const duplicates = new Set();
for (const item of arr) {
if (seen.has(item)) {
duplicates.add(item);
}
seen.add(item);
}
return [...duplicates];
}
console.log(findDuplicates([1, 2, 3, 2, 4, 3, 5])); // [2, 3]
Pagination
function paginate(items, pageSize, pageNumber) {
const start = (pageNumber - 1) * pageSize;
const result = [];
for (let i = start; i < start + pageSize && i < items.length; i++) {
result.push(items[i]);
}
return result;
}
const items = ["a", "b", "c", "d", "e", "f", "g"];
console.log(paginate(items, 3, 2)); // ["d", "e", "f"]
Choosing the Right Loop
| Situation | Best Loop |
|---|---|
| Known number of iterations | for |
| Iterating array values | for...of |
| Iterating object keys | for...in or Object.keys() |
| Condition-based (unknown iterations) | while |
| Must run at least once | do...while |
| Transforming arrays | Array methods (map, filter) |