Skip to main content

Types of loops in JS

In JavaScript, loops split into condition statements (for, while, do...while) and iteration statements (for...in, for...of), with array methods such as forEach alongside them. The difference is what drives the repetition: a counter, a condition, the keys of an object, or the iterator of a collection.

Theory

TL;DR

  • for is the classic loop, used when the number of iterations is known in advance.
  • while is a pre-test loop: its body may never run at all.
  • do...while is a post-test loop: its body is guaranteed to run at least once.
  • for...in walks the enumerable keys of an object, inherited ones included, and does not guarantee order.
  • for...of walks the values of iterables: arrays, strings, Set, Map, arguments.
  • forEach is not a statement but an array method, and break and continue do not work inside it.

Quick example

javascript
const numbers = [10, 20, 30]; for (let i = 0; i < numbers.length; i++) console.log(numbers[i]); // by index for (const value of numbers) console.log(value); // by value numbers.forEach((value, index) => console.log(index, value)); // array method

Counter and condition loops

1. for, the classic loop

Used when the number of iterations is known in advance.

javascript
for (let i = 0; i < 5; i++) { console.log(i); }

Result:

text
0 1 2 3 4

Structure:

javascript
for (initialization; condition; step) { // loop body }
  • initialization runs once at the start;
  • condition is checked before every iteration;
  • step runs after every iteration.

2. while, the pre-test loop

Runs while the condition is truthy (true).

javascript
let i = 0; while (i < 5) { console.log(i); i++; }

Use it when the number of iterations is not known in advance, for example while a queue is not empty, or until the server returns the last page.

3. do...while, the post-test loop

Guaranteed to run at least once, because the condition is checked after the body.

javascript
let i = 5; do { console.log(i); i++; } while (i < 5);

Result:

text
5

The body runs first, and only then is the condition checked.

Iteration statements

4. for...in, iterating object keys

Used to walk the properties of an object.

javascript
const user = { name: 'Tim', age: 25, city: 'Kyiv' }; for (const key in user) { console.log(key, ':', user[key]); }

Result:

text
name : Tim age : 25 city : Kyiv

Details:

  • it visits every enumerable property, including ones inherited through the prototype;
  • it does not guarantee order (integer-like keys come first, in ascending order);
  • it is better not to use it for arrays: keys arrive as strings ('0', '1'), and foreign properties can show up alongside them.

5. for...of, iterating iterable objects

Ideal for arrays, strings, Set, Map and other iterable structures.

javascript
const numbers = [10, 20, 30]; for (const num of numbers) { console.log(num); }

Result:

text
10 20 30

It works with a string too:

javascript
for (const char of 'JS') { console.log(char); }

Unlike for...in, it iterates values, not keys. If you also need the index, use for (const [i, value] of arr.entries()).

6. The forEach() method

It is not a statement but an array method, yet it does the same job: iteration.

javascript
const arr = ['a', 'b', 'c']; arr.forEach((value, index) => { console.log(index, value); });

Result:

text
0 a 1 b 2 c

Details:

  • you cannot use break or continue, and a return inside the callback only ends the current iteration;
  • it is convenient for iteration with no early exit;
  • it skips holes in sparse arrays;
  • it sits next to map, filter, reduce, some and every, which return a result, while forEach always returns undefined.

Comparison table

LoopWhat it iteratesWhen to use itbreak / continue
forindexes, a counterthe iteration count is knownyes
whilenothing, just a conditionthe iteration count is unknownyes
do...whilenothing, just a conditionat least one pass is requiredyes
for...inenumerable object keyswalking object propertiesyes
for...ofvalues of an iterablearrays, strings, Set, Mapyes
forEacharray elementssimple iteration with no exitno

Common mistakes

  • Using for...in on arrays: you get string keys and risk picking up inherited properties. Use for...of or a plain for for arrays.
  • Expecting break to stop a forEach. It does not; if you need an early exit, use for...of, some or find.
  • Forgetting to advance the counter in a while and producing an infinite loop.
  • Confusing do...while with while: the first always runs its body at least once, even when the condition is false from the start.
  • Declaring the counter with var in a loop that has an asynchronous callback: every callback sees the same final value, because var has no block scope. Use let.
  • Calling await inside forEach: the method does not wait for promises, so you need for...of with await, or Promise.all.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.