Ayodele Aransiola

for...of vs for...in in JavaScript

July 13, 2025 By Ayodele
javascript
for...in
for...of

Javascript is a very interesting language, but on the other end, it can also give you sleepless nights or headaches when you are confused. In your head, your logic is well written, and it should work perfectly, but the JavaScript engine will look at your code and smile 😂😀 (what is this one doing?).

In JavaScript, for...of and for...in are two loop constructs that look similar but behave very differently. Many developers, especially beginners, use them interchangeably and end up confused when things don’t work as expected.

Let's look at each of these loop constructs individually before putting them against each other.

Understanding for...in

The for...in loop is used to iterate over all enumerable properties of an object, including inherited ones.

Basic Syntax:

for (const key in object) {
  // access object[key]
}

Example: Looping through a User Profile

You want to display user data on a profile page; you have the userProfile object:

const userProfile = {
  name: "Zainab",
  age: 30,
  country: "Nigeria"
};

for (const key in userProfile) {
  console.log(`${key}: ${userProfile[key]}`);
}

Output:

name: Zainab
age: 30
country: Nigeria

What is happening? Let's go over it together:

On each iteration, key will hold one of the property names ("name", then "age", then "country"). The userProfile[key] will then fetch the value associated with that key. This is a great way to dynamically read and display the contents of any object, especially when you don’t know the property names in advance.

Inherited Properties

const base = { country: "Ghana" };
const user = Object.create(base);
user.name = "John";

for (const key in user) {
  console.log(key);
}

Output:

name
country

To understand what's going on, let's break down each line. An object is defined called base that has one property: country: "Ghana".

The next line const user = Object.create(base) is used to create a new object named user, but it inherits from base.

At this point, user itself is empty, but it has access to all properties that exist in the base object through the prototype chain. That is, user looks like this:

user = {
  __proto__: {
    country: "Ghana"
  }
}

The last line user.name = "John"; is then used to add a new property name directly to the user object. So user now has:

  • An own property: name
  • An inherited property: country (from base)

The for...in loop now iterates over all enumerable properties of the user object, including those inherited through the prototype chain.

If you are hearing about Prototype chain for the first time, don't be scared, in JavaScript it is a mechanism that enables objects to inherit properties and methods from other objects.

Here is the catch: if you only want properties directly on the object, use hasOwnProperty.

for (const key in user) {
  if (user.hasOwnProperty(key)) {
    console.log(key);
  }
}

Output:

name

This loop is will only iterate over the object’s own properties, not the ones it inherits from its prototype. With this explanation, I am sure you are smiling now 🙂 (nodding in agreement). Let's go over the next one for...of.

Understanding for...of

The for...of loop is designed for iterable objects, such as Arrays, Strings, Sets, Maps, and more.

Basic Syntax:

for (const value of iterable) {
  // use value directly
}

Example: Displaying Items in a Cart

const cartItems = ["Laptop", "Phone", "Headphones"];

for (const item of cartItems) {
  console.log(`Added to cart: ${item}`);
}

Output:

Added to cart: Laptop
Added to cart: Phone
Added to cart: Headphones

You're getting the values directly without any need to access them through their index.

It works on strings too.

for (const char of "Code") {
  console.log(char);
}

Output:

C
o
d
e

for...in vs for...of

Featurefor...infor...of
Iterates overEnumerable property names (keys)Iterable values (elements)
Use with objects?YesNo (throws error on plain object)
Use with arrays?Yes (returns index, as strings)Yes (returns actual values)
Use caseLooping over object propertiesLooping through array/string/map/set values

What You Should Avoid

  1. Don't use for...in on arrays if you only care about the values or order. It can produce unpredictable results when properties are added to Array.prototype.
Array.prototype.extra = "hello";

const data = ["a", "b"];
for (const i in data) {
  console.log(data[i]);
}

Output:

a
b
hello
  1. Don't use for...of on objects directly, unless you make the object iterable.
const obj = { a: 1, b: 2 };

for (const val of obj) {
  //Returns - TypeError: obj is not iterable
}

To make it work, convert it:

for (const [key, value] of Object.entries(obj)) {
  console.log(`${key}: ${value}`);
}

Output:

a: 1
b:  2

Conclusion

When working with objects, go with for...in. When working with arrays, strings, or anything iterable, go with for...of. Understanding their difference helps you with the confidence of your program's predictability.