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:
- Target: Primarily designed for plain objects.
- Returns: Property keys (strings).
- Prototype Chain: Includes inherited enumerable
properties unless filtered using
Object.hasOwn()orhasOwnProperty(). - Order: Iteration order is not strictly guaranteed.
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: DeveloperWhat 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:
- Target: Iterable data structures
(
Array,String,Set,Map, etc.). - Returns: Property values directly.
- Prototype Chain: Ignores non-element properties and the prototype chain.
- Objects: Cannot be used directly on plain objects
(throws a
TypeError).
Example:
const colors = ["red", "green", "blue"];
for (const color of colors) {
console.log(color);
}
// Output:
// red
// green
// blueComparing
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
- Use
for...inwhen you need to inspect or loop through the keys/properties of an unindexed, plain JavaScript object. - Use
for...ofwhen you want to iterate over values of an array, string, set, map, or any other iterable collection.