JavaScript for...of vs for...in — Which to Use and Why | TryJS

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.

Overview

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).

How It Works

for...of: values of an iterable

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.

for...in: enumerable string keys

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.

Arrays: use for...of, not for...in

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.

Objects: prefer Object.keys/entries + for...of

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.

Common Mistakes

When to Use It

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.

Runnable Example

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.

Frequently Asked Questions

What is the difference between for...of and for...in?

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.

Can I use for...in with an array?

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.

Why is for...of better than forEach?

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.

How do I get both the index and value with for...of?

Use .entries(): for (const [i, v] of arr.entries()) { ... }. This gives you both without falling back to a classic for-loop.