JavaScript has two loops with almost identical names that do very different things, and mixing them up is one of the most common beginner confusions: for...in iterates over the keys of an object (or the indices of an array), while for...of iterates over the values of an iterable like an array, string, or Map.

for...in: Iterating Over Keys

for...in was designed for plain objects, where it loops through each enumerable property name (the key).

const user = { name: "Alex", age: 28, role: "Developer" };

for (const key in user) {
  console.log(`${key}: ${user[key]}`);
}

Output:

name: Alex
age: 28
role: Developer

for...of: Iterating Over Values

for...of works on iterables — arrays, strings, Maps, Sets — and gives you each value directly, without needing to look it up through an index or key.

const colors = ["red", "green", "blue"];

for (const color of colors) {
  console.log(color);
}

Output:

red
green
blue

Side-by-Side: Using the Wrong One on an Array

Technically, for...in also works on arrays — since array indices are just object keys under the hood — but it gives you the indices as strings, not the values, which is rarely what you actually want:

const scores = [95, 82, 77];

console.log("Using for...in (gives indices as strings):");
for (const i in scores) {
  console.log(i, typeof i);
}

console.log("Using for...of (gives actual values):");
for (const score of scores) {
  console.log(score, typeof score);
}

Output:

Using for...in (gives indices as strings):
0 string
1 string
2 string
Using for...of (gives actual values):
95 number
82 number
77 number

Quick Rule of Thumb

Use for...in for plain objects when you need the property names. Use for...of for arrays, strings, and other iterables when you need the actual values — it's also cleaner than a manual indexed for loop and, unlike forEach(), it can be stopped early with break.