For...in vs for...of in JavaScript
for...in vs for...of
Both for...in and for...of are loop constructs, but they iterate over different things and serve different purposes.
for...in
Iterates over enumerable property keys (strings) of an object:
javascript
const user = { name: "Alice", age: 25, city: "Kyiv" };
for (const key in user) {
console.log(key, user[key]);
}
// "name" "Alice"
// "age" 25
// "city" "Kyiv"for...in with Arrays (Avoid!)
javascript
const arr = ["a", "b", "c"];
// β Iterates over indices as STRINGS, includes inherited properties
for (const index in arr) {
console.log(index, typeof index); // "0" string, "1" string, "2" string
}
// β
Use for...of for arrays
for (const value of arr) {
console.log(value); // "a", "b", "c"
}Prototype Chain Issue
javascript
const parent = { inherited: true };
const child = Object.create(parent);
child.own = "property";
for (const key in child) {
console.log(key); // "own", "inherited" (includes inherited!)
}
// Fix: filter with hasOwnProperty
for (const key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // "own" only
}
}for...of
Iterates over iterable values (elements of arrays, strings, Maps, Sets, etc.):
javascript
// Arrays
for (const value of [1, 2, 3]) {
console.log(value); // 1, 2, 3
}
// Strings
for (const char of "Hello") {
console.log(char); // "H", "e", "l", "l", "o"
}
// Maps
const map = new Map([["a", 1], ["b", 2]]);
for (const [key, value] of map) {
console.log(key, value); // "a" 1, "b" 2
}
// Sets
const set = new Set([1, 2, 3]);
for (const value of set) {
console.log(value); // 1, 2, 3
}for...of with Objects (Not Directly!)
javascript
const obj = { a: 1, b: 2, c: 3 };
// β Objects are NOT iterable
for (const value of obj) {} // TypeError!
// β
Use Object.entries(), Object.keys(), or Object.values()
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}Comparison Table
| Feature | for...in | for...of |
|---|---|---|
| Iterates over | Property keys | Iterable values |
| Works with objects | Yes | No (not iterable) |
| Works with arrays | Yes (but avoid) | Yes β |
| Works with strings | No (use for...of) | Yes β |
| Works with Map/Set | No | Yes β |
| Includes inherited | Yes (prototype chain) | No |
| Returns | String keys | Actual values |
Summary
javascript
// β
for...in β for OBJECTS
for (const key in object) { }
// β
for...of β for ARRAYS, strings, Maps, Sets
for (const value of iterable) { }
// β
Also consider:
Object.keys(obj).forEach(key => {});
Object.entries(obj).forEach(([k, v]) => {});
array.forEach((item, index) => {});Important:
Use for...in for objects (with hasOwnProperty check). Use for...of for arrays and iterables. Never use for...in on arrays β it iterates over string indices and includes inherited properties.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.