Learn the difference between for...of and for...in loops in JavaScript with runnable examples. When to use each, and why for...in surprises most developers.
for...of and for...in look similar but iterate over completely different things. for...of iterates values of any iterable — arrays, strings, Maps, Sets, generators. for...in iterates the enumerable keys of an object, including inherited ones, and is almost never what you want for arrays. Pick for...of for ordered collections and for...in only when you deliberately want every string key of an object (and you probably don't).
Works on any object with a [Symbol.iterator]() method: arrays, strings, Maps, Sets, NodeLists, generators. Gives you the values in iteration order. The 2015+ idiomatic way to loop.
Iterates over every enumerable string-keyed property of an object, including properties inherited through the prototype chain. Order is roughly insertion order for string keys, but numeric keys come first in ascending order.
for...in on an array iterates indices as strings — and also picks up any added properties or inherited pollution. Always use for...of or forEach for arrays.
Instead of for...in, use for (const [key, value] of Object.entries(obj)). This gives you your own enumerable keys only, with their values, in one line.
Use for...of for anything iterable (arrays, strings, Maps, Sets, generators). Use for...in only for debugging or when you genuinely need every enumerable string key of an object — and even then, Object.keys/entries is usually clearer.
const arr = ["a", "b", "c"];
arr.custom = "oops"; // simulate pollution
// for...of: values only, ignores custom
for (const value of arr) {
console.log("of:", value);
}
// for...in: picks up indices AND custom — usually bad
for (const key in arr) {
console.log("in:", key);
}
// Correct: index + value
for (const [i, v] of arr.entries()) {
console.log(`${i} -> ${v}`);
}
// Objects: use Object.entries
const user = { name: "Alice", age: 30 };
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// Works on strings, Maps, Sets
for (const char of "hi") console.log(char);
for (const val of new Set([1, 2, 3])) console.log(val);
Open this example in the TryJS playground to edit and run the code instantly in your browser — no signup needed.
for...of iterates values of any iterable (arrays, strings, Maps, Sets). for...in iterates enumerable string keys of an object, including inherited ones. Use for...of for values, Object.keys/entries for object keys.
You can, but you shouldn't. for...in on an array yields indices as strings and also walks any added or inherited properties. Use for...of, forEach, or a classic for-loop instead.
for...of supports break, continue, and return from an enclosing function; forEach doesn't. for...of also works with await for async iteration. forEach is shorter when you truly want to run a callback on every element and nothing else.
Use .entries(): for (const [i, v] of arr.entries()) { ... }. This gives you both without falling back to a classic for-loop.