for...in
vs. for...of
In JavaScript, both for...in
and for...of
are loop statements that may appear similar at first glance, but they serve different purposes and operate in distinct ways.
This guide explains the key differences between the two and when to use each one effectively.
See also
Differences Between for...in
and for...of
In JavaScript, both for...in
and for...of
are loop constructs that may look similar, but they serve different purposes and work in different ways.
The following table summarizes the key differences between for...in
and for...of
statements.
Category | for...in Statement |
for...of Statement |
---|---|---|
Purpose | Iterates over enumerable property names (keys) of an object | Iterates over the values of iterable objects |
Iteration Target | Property names of a plain object, such as one created with {} or new Object() |
Elements of iterable objects such as arrays, strings, maps, and sets |
Variable Assignment | The property name (key) is assigned to the loop variable | The actual value is assigned to the loop variable |
Prototype Chain | Includes properties inherited through the prototype chain (use with caution) | Does not include inherited properties |
Array Iteration | Technically possible, but not recommended because it may iterate over non-index properties or inherited ones | Well-suited for iterating over array elements in order |
Example | for (const key in object) { ... } |
for (const element of iterable) { ... } |
This table not only highlights the main differences between for...in
and for...of
, but also provides guidance on which loop is better suited for iterating over arrays.
Differences Based on Purpose
Example of for...in
Statement
The for...in
loop is primarily used to enumerate the enumerable property names (keys) of an object, including those inherited through its prototype chain. Note that for...in
only iterates over string-keyed properties and excludes symbol-keyed properties. The example below lists the properties of an object and logs their values.
const person = {
name: "John",
age: 30,
occupation: "developer"
} // Object defined using an object literal
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
age: 30
occupation: developer
In the example above, person[key]
accesses the value of the property named key
in the person
object. During each iteration, the property name and its corresponding value are logged.
Example of for...of
Statement
The for...of
loop is used to sequentially iterate over the values of iterable objects, such as arrays, strings, maps, and sets. The example below iterates over an array and logs each element.
const iterable = [1, 2, 3, 4, 5];
for (const item of iterable) {
console.log(item);
}
2
3
4
5
In the code above, item
is updated with each element of the iterable
array on every iteration, and console.log(item)
outputs the current value.
Differences Based on Iteration Target
To better understand the differences between for...in
and for...of
based on what they iterate over, here are examples applying each loop to different types of data.
for...in
Statement – Object Example
The for...in
loop iterates over the enumerable property names (keys) of a plain object, such as one created with an object literal ({}
) or the new Object()
constructor. It includes properties inherited through the prototype chain.
const person = {
name: "Alice",
age: 25,
occupation: "teacher"
} // Object defined using an object literal
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
age: 25
occupation: teacher
for...in
Statement – Array Example (Not Recommended)
Although for...in
can iterate over array indices, it is generally not recommended for arrays. This is because arrays are objects and for...in
will also iterate over enumerable properties inherited through the prototype chain, which may cause unexpected behavior. Additionally, the iteration order of indices is not guaranteed.
const colors = ["red", "green", "blue"];
for (const index in colors) {
console.log(index); // 0, 1, 2 (indices)
}
for...of
Statement – Array Example
The for...of
loop is well-suited for iterating over the elements of an array in order.
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
console.log(number); // 1, 2, 3, 4, 5
}
for...of
Statement – String Example
The for...of
loop can also iterate over strings, treating them as iterable objects. The example below iterates over each character in a string.
const message = "Hello";
for (const char of message) {
console.log(char);
}
e
l
l
o
Differences Based on Variable Assignment
for...in
Statement – Object Example
In a for...in
loop, the loop variable is assigned the property name (key) of the object.
const person = {
name: "Bob",
age: 30,
occupation: "engineer"
};
for (const key in person) {
const value = person[key];
console.log(`${key}: ${value}`);
}
age: 30
occupation: engineer
for...of
Statement – Array Example
In a for...of
loop, the loop variable is assigned the actual element value.
const numbers = [5, 10, 15];
for (const number of numbers) {
console.log(number); // 5, 10, 15
}
for...of
Statement – String Example
Similarly, in a for...of
loop iterating over a string, the loop variable receives each character.
const message = "Hello";
for (const char of message) {
console.log(char);
}
e
l
l
o
for...in
Statement – Array Index Example (Not Recommended)
When using for...in
on an array, the loop variable receives the array indices. However, because it may include inherited enumerable properties from the prototype chain, this usage is not recommended.
const colors = ["red", "green", "blue"];
for (const index in colors) {
console.log(index); // 0, 1, 2 (indices)
}
These examples clarify the differences in variable assignment between for...in
and for...of
loops, showing what values are assigned to the loop variable.
Differences Based on Prototype Chain
for...in
Statement – Object and Prototype Example
The for...in
loop enumerates both the object's own enumerable properties and those inherited through its prototype chain. The example below shows a custom property added to the prototype and how it is included in iteration.
function Person(name) {
this.name = name;
}
Person.prototype.age = 30;
const person = new Person("Alice");
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
age: 30
for...of
Statement – Array and Prototype Example
The for...of
loop iterates only over the elements of an array and ignores properties inherited through the prototype chain. The example below shows how a method added to the array prototype appears in for...in
but not in for...of
.
Array.prototype.customMethod = function() {
console.log("This is a custom method.");
};
const numbers = [10, 20, 30];
console.log("Using for...of:");
for (const number of numbers) {
console.log(number);
}
console.log('Using for...in:');
for (const index in numbers) {
console.log(index); // 'customMethod' is also logged
}
10
20
30
Using for...in:
0
1
2
customMethod
This example illustrates the key difference in how for...in
and for...of
handle prototype chain properties: for...in
includes inherited enumerable properties, while for...of
only iterates over actual iterable elements.
Conclusion: Choosing Between for...in
and for...of
Loops
While the for...in
and for...of
loops may look similar in syntax, they serve different purposes and behave differently under the hood.
The for...in
loop is used to enumerate the enumerable string-keyed properties of an object, including those inherited through the prototype chain. In contrast, the for...of
loop is designed to iterate over the values of iterable objects, such as arrays, strings, maps, and sets.
- Use
for...in
when you need to loop through the property names of an object, especially when working with object literals or plain objects. - Use
for...of
when you want to loop through the values in an iterable, such as arrays or strings.
Understanding the key differences between these two JavaScript loops will help you choose the right tool for the task and avoid unintended behavior—especially when dealing with arrays or inherited properties.
Specifications
Specification | |
---|---|
for...in, for...of
|
ECMAScript Language Specification #sec-for-in-and-for-of-statements |
Browser compatibility
Statement |
Desktop Chrome
|
DesktopDesktop Edge
|
Desktop Firefox
|
Safari
|
---|---|---|---|---|
for...in
|
1 | 12 | 1 | 1 |
for...of
|
38 | 12 | 13 | 7 |