JavaScript  

Why is for...of not iterable on plain JavaScript objects, and how can I fix it?

🚀 Introduction

In JavaScript, looping is something we do very often. The for...of loop is a modern and simple way to go through elements of arrays, strings, Maps, or Sets. But if you try to use for...of with a plain object (like {}), JavaScript throws an error. This can be confusing for beginners who expect it to work the same way as with arrays.

🔍 Why is for...of Not Iterable on Plain Objects?

The main reason is that for...of only works on iterable objects. An iterable is an object that has a special method called Symbol.iterator, which tells JavaScript how to go through its items one by one. Arrays, strings, Maps, and Sets already have this built-in method.

Plain objects ({}) do not have the Symbol.iterator method by default. This means JavaScript does not know how to loop through them with for...of. That’s why you see the error:

TypeError: object is not iterable

🛠️ How to Fix It

There are several ways you can work around this problem depending on what you want to loop through.

1. Using Object.keys()

Object.keys() gives you all the keys of an object in an array. Since arrays are iterable, you can use for...of on them.

const person = { name: "Alice", age: 25 };

for (let key of Object.keys(person)) {
  console.log(key, person[key]);
}

👉 Use this when you only need the property names (keys).

2. Using Object.values()

Object.values() returns all the values of an object inside an array.

const person = { name: "Alice", age: 25 };

for (let value of Object.values(person)) {
  console.log(value);
}

👉 Use this when you only care about the values.

3. Using Object.entries() 

Object.entries() gives both keys and values together as small arrays.

const person = { name: "Alice", age: 25 };

for (let [key, value] of Object.entries(person)) {
  console.log(key, value);
}

👉 Use this when you want both keys and values at the same time.

4. Making an Object Iterable

If you really want to use for...of directly on an object, you can make it iterable by adding a custom Symbol.iterator method.

const person = { name: "Alice", age: 25 };

person[Symbol.iterator] = function* () {
  for (let key of Object.keys(this)) {
    yield [key, this[key]];
  }
};

for (let [key, value] of person) {
  console.log(key, value);
}

👉 This way, you define how the object should be looped, and now for...of works directly on it.

⚡ When to Use Each Approach

  • ✅ Use Object.keys() when you only need the property names.
  • ✅ Use Object.values() when you only need the values.
  • ✅ Use Object.entries() when you want both keys and values together.
  • ✅ Use a custom iterator when you need complete control over how your object is looped.

📌 Summary

The for...of loop in JavaScript only works on iterable objects, and plain objects are not iterable by default because they don’t have the Symbol.iterator method. That’s why you cannot use for...of directly on them. To fix this, you can convert objects into arrays using Object.keys(), Object.values(), or Object.entries(), or you can add your own custom iterator. Each method has its own use case, so you can pick the one that best fits your needs.