JavaScript for…in vs for…of: Key Differences

In JavaScript, both for...in and for...of statements are used for iteration, but they serve fundamentally different purposes based on what data they access. The for...in loop iterates over the enumerable property keys (names or indexes) of an object, while the for...of loop iterates over the values of an iterable collection such as an Array, Map, or Set. Understanding when and how to use each loop prevents common bugs related to unexpected property inheritance and unintended data types.

What is the for...in Loop?

The for...in loop iterates over all enumerable properties of an object, including inherited properties from its prototype chain. It returns the keys (or property names) as strings.

Key Characteristics:

Example:

const user = { name: "Alice", age: 25, role: "Developer" };

for (const key in user) {
  console.log(`${key}: ${user[key]}`);
}
// Output:
// name: Alice
// age: 25
// role: Developer

What is the for...of Loop?

Introduced in ES6, the for...of loop iterates directly over the values of an iterable object. An iterable is any object that implements the [Symbol.iterator] method, such as Array, String, Map, Set, TypedArray, or arguments.

Key Characteristics:

Example:

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

for (const color of colors) {
  console.log(color);
}
// Output:
// red
// green
// blue

Comparing for...in and for...of on Arrays

Using for...in on arrays is a common source of bugs because it returns array indexes as strings rather than the element values. Furthermore, it will loop over manually added properties or prototype extensions.

const list = ["a", "b", "c"];
list.customProperty = "extra";

// for...in loops over keys/indexes and custom properties
for (const index in list) {
  console.log(index); // "0", "1", "2", "customProperty"
}

// for...of loops only over the element values
for (const value of list) {
  console.log(value); // "a", "b", "c"
}

Summary Comparison

Feature for...in for...of
Primary Target Objects Iterables (Arrays, Sets, Maps, Strings)
Output Keys / Property Names Values
Output Type Strings Matches the element’s type
Prototype Properties Included (if enumerable) Ignored
Works on Plain Objects Yes No (requires Object.entries(), Object.keys(), etc.)

When to Use Which