Skip to content
Theory · Conditions and loops · lesson 8 of 13

The for…in loop

In the previous lesson, for…of went down the shopping list and gave the items themselves: milk, bread, apples. Sometimes you need not the items but their numbers, for example to write "1.", "2.", "3." next to them.

Picture a cloakroom. You hand in your jacket and get a tag that says "12". There is a number on the tag, but nobody adds tags together: it is a label, not a quantity.

for…of has a similar loop, for…in. It goes through the indexes of an array, not its elements. And the indexes arrive exactly like those tags: as strings, not numbers.

Indexes instead of values

Let's run for…in over an array of three letters and print each index together with its type:

JavaScript
const letters = ["x", "y", "z"];

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

Step by step:

  1. On the first iteration, i gets the index of the first element, the string "0".
  2. typeof i gives "string", and the program prints 0 string.
  3. Next, i gets "1" and "2", and the type stays the same.
  4. The indexes run out, and the loop stops by itself.

The loop never gave the letters "x", "y" and "z" themselves. There are no quotes in the output either: console.log prints strings without them, so "0" looks like a number.

Why indexes are strings

In JavaScript, an array index works as the name of a slot, and slot names are always stored as strings. for…in goes through exactly these names, so it gives "0", "1" and "2".

The type of the index matters when you compare. Inside the loop, the check i === 0 is always false: strict equality does not convert types, and the string "0" is not equal to the number 0. Compare with a string, i === "0", or with the number made from it, Number(i) === 0.

Here the cloakroom analogy stops working. A tag cannot become a quantity, but an index string can: Number(i) turns "2" into the number 2.

Over a string

Over a string, for…in also goes through index strings, not characters:

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

The string "ok" has two characters, so the loop gives two indexes: "0" and "1". The letters o and k themselves come from for…of. A string of five characters would have indexes from "0" to "4".

Which loop to choose

The rule is short:

  • you need the elements of an array or the characters of a string: use for…of;
  • you need the indexes: for…in gives them, but as strings.

Interviewers often ask for the difference between these two loops. The short answer: for…of gives values, and for…in gives indexes as strings.

Common mistake

An index from for…in is used as a number:

JavaScript
const scores = [10, 20];

for (const i in scores) {
    console.log(i + 1); // ✗
}

There is no error, but the program prints 01 and 11, not 1 and 2. The index i is the string "0", and + with a string joins instead of adding.

If you need a number, convert the index:

JavaScript
const scores = [10, 20];

for (const i in scores) {
    console.log(Number(i) + 1);
}
// 1
// 2

If you need the elements, write for…of.

Key points

  • for…in goes through the indexes of an array or a string, not the values.
  • The indexes arrive as strings: "0", "1", "2".
  • + with an index string joins; Number(i) gets a number from the index.
  • For values, go to for…of; for indexes, go to for…in.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way