Skip to main content

for...in vs for...of

For In: Loops over the Keys.

for...in works with those properties whose enumerable flag is set to true.

  • Enumerable flag for properties created via simple assignment or property initializer are by default true.
  • Enumerable flag for properties created via Object.defineProperty are by default false.

it's used to iterate over all enumerable properties of an object, including inherited enumerable properties. This iteration statement can be used with arrays, strings or plain objects, but not with Map or Set objects.

for (key in object) {
// body of for...in
}

For Of: Loops over the Values

for...of loop works only with iterable objects. In JavaScript, iterables are objects which can be looped over.

String, Array, TypedArray, Map, and Set are all built-in iterables, because each of their prototype objects implements an @@iterator method. So, for...of loop works on the mentioned object types.

Object in JavaScript is not iterable by default. So, for...of loop does not work on objects.

In simple words, for...of works with strings and arrays but not with objects.

for...of - How it works?

for...of is a method, introduced in ES2015, for iterating over iterable collections. These are objects that have a [Symbol.iterator] property.

The [Symbol.iterator] property allows us to manually iterate over the collection by calling the [Symbol.iterator]().next() method to retrieve the next item in the collection.

const myArray = ['a','b','c', 'd'];
const iterator = myArray[Symbol.iterator]();
console.log( iterator.next().value )
console.log( iterator.next().value )
console.log( iterator.next().value )
console.log( iterator.next().value )

// Output: a, b, c, d

The for...of syntax is essentially a wrapper around the [Symbol.iterator] to create loops. It uses the following syntax

for (value of iterable) {
// do stuff
}
const myMap = new Map([['name', 'Rajesh'], ['mark', 73], ['school', 'G.H.S, School']]);

for (let val of myMap)
console.log(val);
/*
// Output
['name', 'Rajesh']
['mark', 73]
['school', 'G.H.S, School']
*/

for (let [key, val] of myMap)
console.log(key +': '+ val);

// Output
name: Rajesh
mark: 73
school: G.H.S, School

for...of and NodeLists

Finally, another really useful case for for...of is in iterating of NodeLists. When we query the document for a group of elements, what we get returned is a NodeList, not an Array. This means that we can't iterate over the list using Array methods like forEach.

To solve this, we can either convert it to an Array using Array.from(), or use the for...of loop, which is applicable to more than just Arrays and array-like object.

const elements = document.querySelectorAll('.foo');

for (const el of elements) {
el.addEventListener('click', doSomething);
}

Bonus - forEach

const arr = ['B', 'a', 'b', 'e'];
arr.forEach(el => console.log(el));

// Output
'B'
'a'
'b'
'e'