# JavaScript Loops

> Learn when to use for, while, do...while, for...of, for...in, and forEach() to iterate over JavaScript data.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-04-11 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/javascript-loops/

<!-- TOC -->

- [Introduction](#introduction)
- [`for`](#for)
- [forEach](#foreach)
- [`do...while`](#dowhile)
- [`while`](#while)
- [`for...in`](#forin)
- [`for...of`](#forof)
- [`for...in` vs `for...of`](#forin-vs-forof)

<!-- /TOC -->

## Introduction

[JavaScript](https://flaviocopes.com/javascript/) provides several ways to repeat code or iterate over data.

Use `for...of` for iterable values such as arrays. Use `Object.keys()` when you need an object's own enumerable property names. Use a classic `for` or `while` loop when you need direct control over the iteration.

## for

```js
const list = ['a', 'b', 'c']
for (let i = 0; i < list.length; i++) {
  console.log(list[i]) //value
  console.log(i) //index
}
```

- You can interrupt a `for` loop using `break`
- You can fast forward to the next iteration of a `for` loop using `continue`

## forEach

`forEach()` is an Array method. It calls a function once for each existing array element:

```js
const list = ['a', 'b', 'c']
list.forEach((item, index) => {
  console.log(item) //value
  console.log(index) //index
})

//index is optional
list.forEach(item => console.log(item))
```

You cannot stop a `forEach()` early with `break`. Use `for...of` when you need to exit the loop.

## do...while

```js
const list = ['a', 'b', 'c']
let i = 0
do {
  console.log(list[i]) //value
  console.log(i) //index
  i = i + 1
} while (i < list.length)
```

You can interrupt a `do...while` loop using `break`:

```js
let attempts = 0

do {
  attempts = attempts + 1
  if (attempts === 3) break
} while (attempts < 10)
```

You can also jump to the next iteration using `continue`. Make sure the loop condition can still change, or you can create an infinite loop.

## while

```js
const list = ['a', 'b', 'c']
let i = 0
while (i < list.length) {
  console.log(list[i]) //value
  console.log(i) //index
  i = i + 1
}
```

You can interrupt a `while` loop using `break`:

```js
while (true) {
  if (something) break
}
```

and you can jump to the next iteration using `continue`:

```js
let i = 0

while (i < 5) {
  i = i + 1
  if (i === 3) continue

  console.log(i)
}
```

The difference is that `do...while` always runs its body at least once.

## for...in

`for...in` iterates over an object's enumerable string property names, including inherited ones.

```js
const person = {
  name: 'Flavio',
  country: 'Italy'
}

for (const property in person) {
  if (!Object.hasOwn(person, property)) continue

  console.log(property) //property name
  console.log(person[property]) //property value
}
```

For own enumerable properties, `Object.keys()` is often clearer:

```js
for (const property of Object.keys(person)) {
  console.log(property)
  console.log(person[property])
}
```

Avoid `for...in` for arrays. It returns string property names and can include non-index properties. See the [MDN `for...in` reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) for the enumeration rules.

## for...of

[ES6](https://flaviocopes.com/es6/) introduced the `for...of` loop. It visits the values produced by an iterable, and supports `break` and `continue`:

```js
//iterate over the value
for (const value of ['a', 'b', 'c']) {
  console.log(value) //value
}

//get the index as well, using `entries()`
for (const [index, value] of ['a', 'b', 'c'].entries()) {
  console.log(index) //index
  console.log(value) //value
}
```

Notice the use of `const`. This loop creates a new scope in every iteration, so we can safely use that instead of `let`.

Arrays, strings, Maps, Sets, and many DOM collections are iterable. Plain objects are not iterable by default.

## for...in vs for...of

The difference is:

- `for...of` iterates values defined by an object's iterator
- `for...in` iterates enumerable string property names, including inherited ones

The [MDN `for...of` reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) has more examples for custom iterables and early exits.
