Loops: for, while, for…of and for…in

Repeat work with each kind of loop, control loops with break and continue, and pick the right loop for arrays and objects.

  • Beginner
  • 8 min read
  • Updated 17 Oct 2026

What you will learn

  • Loop over arrays with for…of
  • Avoid for…in on arrays
  • Write counting loops with for and condition-based loops with while
  • Control loops with break and continue

Loops repeat code: once for each item in a list, a set number of times, or until something changes. JavaScript has several kinds of loop, and choosing the right one makes code shorter and safer. This lesson covers each loop, how to stop or skip, and which loop suits arrays and objects.

The for loop

The classic for loop counts. It has three parts in its brackets, separated by semicolons:

JavaScript
for (let i = 1; i <= 3; i++) {
  console.log(`Round ${i}`);
}
// Round 1
// Round 2
// Round 3
  1. Initialisation, let i = 1, runs once before the loop starts.
  2. Condition, i <= 3, is checked before every pass. The loop stops when it is false.
  3. Update, i++, runs after every pass.

Use let for the counter, not const, because it changes. The counter only exists inside the loop.

A for loop can walk through an array by index. Arrays start at index 0, so the condition is i < length, not <=:

JavaScript
const colours = ["red", "green", "blue"];

for (let i = 0; i < colours.length; i++) {
  console.log(`${i}: ${colours[i]}`);
}
// 0: red
// 1: green
// 2: blue

Getting the boundary wrong by one, an off-by-one error, is one of the most common bugs in programming. That is a big reason to prefer for...of for arrays.

for…of: loop over values

for...of gives you each value of an array, or any other iterable such as a string, in turn. There is no counter to get wrong:

JavaScript
const colours = ["red", "green", "blue"];

for (const colour of colours) {
  console.log(colour);
}
// red
// green
// blue

You can use const here because each pass creates a fresh variable. This is the loop to reach for first whenever you need every item of an array.

It works on strings too, one character at a time:

JavaScript
for (const letter of "Hi!") {
  console.log(letter);
}
// H
// i
// !

If you also need the index, use the array's entries() method with destructuring, which lesson 23 explains in full:

JavaScript
for (const [index, colour] of colours.entries()) {
  console.log(`${index + 1}. ${colour}`);
}
// 1. red
// 2. green
// 3. blue

Later in the course you will meet NodeLists of page elements, Maps and Sets. for...of works on all of them. Lesson 44 explains the iteration protocol that makes this possible.

for…in: loop over object keys

for...in loops over the property names (keys) of an object:

JavaScript
const course = { title: "JavaScript", lessons: 54, level: "beginner" };

for (const key in course) {
  console.log(`${key}: ${course[key]}`);
}
// title: JavaScript
// lessons: 54
// level: beginner

The course[key] syntax reads a property whose name is held in a variable. Lesson 13 covers it.

Avoid for…in on arrays

for...in works on arrays, but it gives you keys, and keys are always strings:

JavaScript
const scores = [10, 20];

for (const i in scores) {
  console.log(i, typeof i);
}
// 0 string
// 1 string

That leads to bugs such as i + 1 giving "01". for...in can also pick up extra properties that have been added to an array or inherited from elsewhere. Use for...of for arrays and keep for...in for plain objects.

Even for objects, many developers prefer Object.keys() or Object.entries() with for...of, which only include the object's own properties. Lesson 24 covers those methods.

while: loop until a condition changes

A while loop repeats as long as its condition is true. Use it when you do not know in advance how many passes you need:

JavaScript
let balance = 100;
let months = 0;

while (balance > 0) {
  balance -= 30;
  months++;
}

console.log(`Paid off in ${months} months`);
// Paid off in 4 months

The condition is checked before every pass, so if it starts out false, the body never runs.

Infinite loops

If the condition never becomes false, the loop never ends. In a browser, the tab freezes because JavaScript cannot do anything else while the loop runs:

JavaScript
// Do not run this
let count = 0;
while (count < 5) {
  console.log(count);
  // Forgot count++
}

Make sure something inside every while loop moves it towards its end. If you do freeze a tab, close it; the browser will eventually offer to stop the script.

do…while

A do...while loop checks its condition after each pass, so the body always runs at least once:

JavaScript
let attempts = 0;

do {
  attempts++;
  console.log(`Attempt ${attempts}`);
} while (attempts < 2);
// Attempt 1
// Attempt 2

It is rarely needed, but it suits "do something, then decide whether to repeat".

break and continue

break leaves a loop immediately. Use it when you have found what you were looking for:

JavaScript
const orders = [12, 45, 230, 18];

for (const total of orders) {
  if (total > 100) {
    console.log(`First large order: ${total}`);
    break;
  }
}
// First large order: 230

continue skips the rest of the current pass and moves on to the next:

JavaScript
const names = ["Ada", "", "Grace", ""];

for (const name of names) {
  if (name === "") {
    continue;
  }
  console.log(name);
}
// Ada
// Grace

Both work in for, for...of, for...in, while and do...while loops. Use them sparingly; a loop with several break and continue statements becomes hard to follow.

Building up a result

A common pattern is to start with an empty or zero value and update it on each pass:

JavaScript
const prices = [4.5, 12, 3.25];
let total = 0;

for (const price of prices) {
  total += price;
}

console.log(total);
// 19.75
JavaScript
const words = ["learn", "build", "ship"];
const shouted = [];

for (const word of words) {
  shouted.push(word.toUpperCase());
}

console.log(shouted);
// ["LEARN", "BUILD", "SHIP"]

These patterns are so common that arrays have built-in methods for them, such as map(), filter() and reduce(). Lesson 22 covers them, and you will often use them instead of a loop. Loops remain the right choice when you need break, when you work with something that is not an array, or when a plain loop is simply clearer.

Which loop to use

You want toUse
Go through every item of an array, string or other iterablefor...of
Count, or step through numbers in a patternfor
Repeat until a condition changeswhile
Go through the keys of a plain objectfor...in, or Object.keys() with for...of
Transform or filter an array into a new oneArray methods (lesson 22)

Summary

  • for loops count, with an initialisation, a condition and an update. Watch for off-by-one errors.
  • for...of gives you each value of an array or other iterable, and is the default for arrays.
  • for...in gives you an object's keys as strings. Do not use it on arrays.
  • while repeats as long as a condition is true; make sure something ends it.
  • break leaves a loop; continue skips to the next pass.
  • Building a result in a loop is common, and array methods often do it more neatly.

Further reading