Javascript For In Vs For Of

6 min read

Introduction

When working with JavaScript, choosing the right looping construct can dramatically affect both code readability and performance. of* is essential for writing clean, efficient, and maintainable JavaScript code. of** loop. Here's the thing — in** loop and the *for... The two most common iteration methods are the **for...in vs *for...Understanding the nuances between *for...This article breaks down the syntax, use cases, and key differences, helping you decide which loop fits your specific scenario.

Understanding for...in Loop

The for...Which means in loop is designed to iterate over the enumerable properties of an object. It is particularly useful when you need to access both keys and values, especially when dealing with plain JavaScript objects or arrays (though arrays have their own quirks).

You'll probably want to bookmark this section.

Syntax

for (let property in object) {
  console.log(property, object[property]);
}

How It Works

  1. Enumerates keys – The loop variable receives the property name (a string for objects, a numeric index for arrays).
  2. Checks enumerability – Only properties that are own and enumerable appear, unless Object.prototype properties are inherited.
  3. No guarantee of order – The ECMAScript specification does not enforce any particular order for object keys, making for...in unpredictable for arrays.

Typical Use Cases

  • Iterating over object keys (e.g., configuration objects).
  • Transforming object data into a new format.
  • Checking property existence with hasOwnProperty.

Common Pitfall

Because for...in also includes inherited enumerable properties, you must guard against unintended iterations:

const base = { shared: 'value' };
const derived = Object.create(base);

for (let key in derived) {
  console.log(key); // logs 'shared' as well as any own properties
}

Always use Object.prototype.hasOwnProperty.call(obj, key) to ensure you are iterating over own properties only Surprisingly effective..

Understanding for...of Loop

The for...of loop, introduced in ES6, iterates over iterable objects—most commonly arrays, strings, maps, sets, and NodeLists. It provides a clean, intuitive way to access values directly, without needing to know the index or property names That alone is useful..

Syntax

for (let value of iterable) {
  console.log(value);
}

How It Works

  1. Obtains an iterator – The iterable object supplies an @@iterator method.
  2. Returns values – Each iteration yields the value from the iterator.
  3. Stops when done – The loop terminates when the iterator returns { done: true }.

Typical Use Cases

  • Processing array elements without manual indexing.
  • Iterating over strings character by character.
  • Working with Maps and Sets where you need both key and value (using entry variable).
  • Traversing DOM NodeLists (e.g., document.querySelectorAll).

Example with a Map

const myMap = new Map([['name', 'Alice'], ['age', 30]]);
for (let [key, value] of myMap) {
  console.log(`${key}: ${value}`);
}

Key Differences

Feature *for...Worth adding: Faster for arrays and iterables because it directly accesses values. of*
Target Enumerable properties of an object. , array order, insertion order for Maps). Iterable objects (arrays, strings, maps, sets, etc.
Inheritance Includes inherited enumerable properties (needs hasOwnProperty guard).
Variable Receives property names (strings or numbers).
Use Case Object manipulation, configuration iteration. ). Even so, Does not include inherited properties; only iterates over the iterable’s own elements. On top of that, in*
Performance Generally slower for large arrays because of key lookups. And Receives values (or [key, value] for Maps). Practically speaking,
Order Unspecified; may vary across JavaScript engines. Defined by the iterable’s specification (e.

When to Use Each Loop

Choose for...in When

  • You need to inspect or modify object properties (e.g., cloning an object).
  • You are working with plain objects where keys are not sequential numbers.
  • You must check property existence using hasOwnProperty.
function cloneObject(src) {
  const copy = {};
  for (let key in src) {
    if (Object.prototype.hasOwnProperty.call(src, key)) {
      copy[key] = src[key];
    }
  }
  return copy;
}

Choose for...of When

  • You are processing arrays, strings, or custom iterables.
  • You want direct access to values without dealing with indices.
  • You need clean, readable code for simple iteration.
const numbers = [3, 7, 12];
let sum = 0;
for (let num of numbers) {
  sum += num;
}
console.log(sum); // 22

Code Examples Demonstrating the Differences

Example 1: Iterating Over an Object

const user = { name: 'Bob', age: 25, city: 'NYC' };

for (let prop in user) {
  console.log(`${prop}: ${user[prop]}`);
}

Output

name: Bob
age: 25
city: NYC

Example 2: Iterating Over an Array

const fruits = ['apple', 'banana', 'cherry'];

for (let fruit of fruits) {
  console.log(fruit);
}

Output

apple
banana
cherry

Example 3: Mixing Both Loops

const config = { timeout: 5000, retries: 3, enabled: true };
const entries = Object.entries(config); // [['timeout', 5000], ['retries', 3], ['enabled', true]]

for (let [key, value] of entries) {
  console.log(`${key} = ${value}`);
}

Output

timeout = 5000
retries = 3
enabled = true

Performance Considerations

  • Large Arrays: *for...of

  • Large Arrays: for...of is generally faster than for...in because it iterates directly over values rather than performing property lookups on string keys. For arrays with tens of thousands of elements, this difference becomes noticeable Easy to understand, harder to ignore..

  • Small Objects: For small plain objects, the performance gap is negligible, so readability and correctness should take priority.

  • Maps and Sets: for...of works naturally with Map and Set objects, iterating in insertion order. for...in would not work as intended since these are not plain objects with string-keyed properties in the traditional sense.

Benchmark Snapshot

const largeArray = new Array(1_000_000).fill(0);

// for...Because of that, of');
for (let val of largeArray) {}
console. Which means time('for... Consider this: of — typically ~15-20% faster
console. timeEnd('for...

// for...That's why in — significantly slower due to key coercion and lookup
console. Think about it: time('for... That said, in');
for (let idx in largeArray) {}
console. timeEnd('for...

**Typical Result**

for...of: 4ms for...in: 25ms


## Common Pitfalls and How to Avoid Them

### Pitfall 1: Forgetting `hasOwnProperty` in *for...in*

Without a guard, inherited properties from `Object.prototype` (like `toString` or `valueOf`) may appear in your loop:

```javascript
const obj = Object.create({ inherited: true });
obj.own = 'hello';

for (let key in obj) {
  console.log(key); // logs both 'inherited' and 'own'
}

Fix:

for (let key in obj) {
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
    console.log(key); // logs only 'own'
  }
}

Pitfall 2: Using for...in on Arrays

While technically possible, for...in on arrays can iterate over non-numeric keys and does not guarantee index order:

const arr = ['a', 'b', 'c'];
arr.custom = 'extra';

for (let i in arr) {
  console.log(i); // logs '0', '1', '2', AND 'custom'
}

Fix: Always prefer for...of for arrays to avoid this unexpected behavior But it adds up..

Pitfall 3: Assuming for...of Works on Plain Objects

Plain objects are not iterable by default. Attempting for...of on one throws a TypeError:

const obj = { a: 1, b: 2 };
for (let val of obj) {
  // TypeError: obj is not iterable
}

Fix: Convert the object using Object.keys(), Object.values(), or Object.entries():

for (let val of Object.values(obj)) {
  console.log(val); // 1, 2
}

Summary

Aspect for...in for...of
Best For Object property enumeration Array and iterable traversal
Iterates Over Keys (strings/Symbols) Values
Inherited Props Yes (requires guard) No
Array-Safe No Yes
Performance Slower for arrays Faster for arrays and iterables

Conclusion

Understanding the distinction between for...in and for...of is essential for writing correct, efficient, and maintainable JavaScript. In practice, the two loops serve fundamentally different purposes: for... in is designed for inspecting the enumerable properties of objects, while for...Because of that, of is built for iterating over the values of iterables like arrays, strings, maps, and sets. Choosing the wrong loop can introduce subtle bugs—such as accidentally iterating over inherited properties or attempting to loop over a non-iterable object. By matching the loop construct to the data structure at hand and guarding against common pitfalls, developers can ensure their code behaves predictably and performs well across all scenarios.

New on the Blog

New Stories

Keep the Thread Going

Good Reads Nearby

Thank you for reading about Javascript For In Vs For Of. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home