JS for..of and for..in

When to use for..of and for..in in Javascript?

Looping through Arrays and Objects

By definition, the main difference between for..of and for..in is on where each of them looks as they loop through an array or object. As explained on Stackoverflow by Willem van der Veen,

[1] for..in iterates over all the enumerable property keys of an object while

[2] for..of iterates through the values of an iterable object.

Idk if stating this will make the understanding better, but analyze these statements,

[1] He died in agony.

[2] He died of agony.

The first sentence implies that he died while in agony while the latter implies that he died because of agony.

I tried to make sense on the difference on the use of of and in that I tried to look at it grammatically but I failed - and miserably at it.(:pepesolaugh:)

Anyway, it's better if we just remember it as

keys in object and values of array.

... You may notice the intentional correlation of object to in and array to of. I chose to do these to emphasize an important point - which is my main reason of writing this article, that using for...in with objects will let you iterate over the keys in the object but using for...of will trigger an error.

I demonstrated this using a code snippet,

const mObj = {item1: 0, item2: 1};

for (const item of (mObj)) { //Uncaught TypeError: mObj is not iterable
  console.log('of', item);
}

/* outputs: 
*  "in", "item1"
*  "in", "item2"
*/
for (const item in mObj) {
    console.log('in', item);
}

On the other hand, both for..of and for..in works just fine with arrays. However, I don't really see the use of using for..in in arrays as it just iterates over the index which is already the case when using the traditional for loop.

const mArr = ['js', 'is', 'real', 'pain']; 

/* outputs:
*  "of", "js"
*  "of", "is"
*  "of", "real"
*  "of", "pain" 
*/
for (const item of mArr) {
    console.log('of', item);
}

/* outputs:
*  "in", "0"
*  "in", "1"
*  "in", "2"
*  "in", "3"
*/
for (const item in mArr) {
    console.log('in', item);
}

Importantly, even though you can't use for..of in objects as it is, for..of is also quite powerful with objects when used with Object.entries() as shown in this code snippet.

const mObj = {item1: 0, item2: 1};

/* outputs: 
*  "of", ["item1", 0]
*  "of", ["item2", 1]
*/
for (const item of Object.entries(mObj)) {
  console.log('of', item);
}

Ref: StackOverflow

Ref: Cover Image

Ref: OG Image

Dinys Monvoisin's photo

Would not it better off saying that for...of is used with array type values only rather than saying it generates an error message?

Gabriel Drix's photo

Good point, I only chose to describe it that way to emphasize it haha.

Dinys Monvoisin's photo

It make it confusing and imagine someone who is starting.

Gabriel Drix's photo

I want to hear what you think, I will appreciate your comments :)