DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,673 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Difference between for...of and for...in loop in JavaScript.
Swastik Yadav
Swastik Yadav

Posted on • Updated on

Difference between for...of and for...in loop in JavaScript.

Hello Everyone,

The difference between for-of and for-in loop really troubled me when I was learning JavaScript. And with this blog I will try to clear the confusion once and for all.

Let's understand them one by one.

for...of Loop

The MDN Definition:

The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables.

I know that's not the explanation you came here for, So let me explain.

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 instance:

cosnt str = "Hello World";

for(element of str) {
  console.log(element);
}
// H e l l o " " W o r l d
Enter fullscreen mode Exit fullscreen mode

for...in Loop

The MDN Definition

The for...in statement iterates over all enumerable properties of an object that are keyed by strings (ignoring ones keyed by Symbols), including inherited enumerable properties.

Explanation:

So, for...of does not work with objects (non iterables), Then how do we loop over keys and values of an object? And the answer is for...in loop.

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.

For instance:

const student = {
    registration: "123456",
    name: "Sandeep",
    age: 33,
}

for(key in student) {
  console.log(key, student[key]);
}
/*
registration "123465"

name "Sandeep"

age 33
*/
Enter fullscreen mode Exit fullscreen mode

Now let's add a new property (marks) to student object and set it's enumerable flag to false. With enumerable flag set to false, marks key won't appear in result of for...in loop.

const student = {
    registration: "123456",
    name: "Sandeep",
    age: 33,
}

Objec.defineProperty(student, "marks", {
  value: 98,
  enumerable: false,
})

console.log(student.marks);
// 98

for(key in student) {
  console.log(key, student[key]);
}
/*
registration "123465"

name "Sandeep"

age 33
*/

// marks key does not show up in the for...in loop result.
Enter fullscreen mode Exit fullscreen mode

for...in also works with strings and arrays, because enumerable flag for string and array properties are also by default true.

  • In simple words use for...in to loop over objects. Although for...in works with strings and arrays, but it is not suggested to use that way.

Conclusion

  • for...of - Use to loop over strings and arrays.
  • for...in - Use to loop over objects.

That's it for this post.

If you enjoyed this post, consider joining my 8020 NewsLetter for more epic content on building your skillset.

Giveaway: I am giving away my paid 8020 CSS E-Book if you subscribe to the newsletter. Giveaway valid only for this weekend.

Thank You!

Top comments (26)

Collapse
 
lukeshiru profile image
Luke Shiru

Remember to use const or let for the tracking variable (key):

for (const key in student) {
    console.log(key, student[key]);
}

for (const student of students) {
    console.log(student);
}
Enter fullscreen mode Exit fullscreen mode

And you have a typo in your last example, it should say Object not Objec.

Finally, remember that you can just user map or forEach instead of for..of or for..in:

const student = {
    registration: "123456",
    name: "Sandeep",
    age: 33
};

Object.entries(student).forEach(([key, value]) => console.log(key, value));
Enter fullscreen mode Exit fullscreen mode

Cheers!

Collapse
 
nanythery profile image
Nadine M. ThΓͺry

I was about to ask what's the difference between forEach, which I tend to use a lot and these other methods. Honestly, I use forEach because I learnt it first and I didn't feel need to learn others haha.
Are these methods a better practice or a refactor method?

Collapse
 
swastikyadav profile image
Swastik Yadav Author

Hey Nadine,

forEach is an Array method just like Array.prototype.map and Array.prototype.filter. The difference between forEach and other Array methods is that unlike "map" and "filter", "forEach" does not return the array it always returns undefined.

I hope this cleared the confusion.

Thanks for bringing this up in the comments. 😊

Collapse
 
ddasb profile image
Damien Da Silva Bregieiro

For of came with ES2015 and is currently a better practice :

  • More readable
  • No callbacks
  • Faster (Refering to some benchmark but not sure)
  • You can also use .entries() and destructuring
Thread Thread
 
lukeshiru profile image
Luke Shiru

"better practice" is subjective. I find map and forEach more readable pretty much every time, and they are faster if the JS engine optimizes it (and V8 does).

Collapse
 
leob profile image
leob • Edited on

I can never remember which one is which, always need to look it up ... do you happen to know a clever mnemonic to remember it?

You could say "of" is for "o"bject and "in" is an "index" (key) but unfortunately that's not good (for ... of does NOT work with objects).

In fact "for of" (not "for in") is for "iterables" ... so this is a mnemonic that's just the wrong way around, lol.

Collapse
 
msid01 profile image
Siddhesh Mungekar

You can remember it as
of - objects iterable
in - enumerable objects

I hope it won't be confusing πŸ˜ƒ

Collapse
 
leob profile image
leob

Hmm yeah that might work ... I can't come up with anything better either lol

Thread Thread
 
drbatroni profile image
DrBatroni

I use it like this:
in - iterate in object
of - iterate over something (string/array)

Thread Thread
 
leob profile image
leob

Yes I like that! best one I've seen until now ...

Collapse
 
narayand16 profile image
Narayan Deshmukh

Thanks , this will really help !

Thread Thread
 
swastikyadav profile image
Swastik Yadav Author

I am glad that this helped, Narayan 😊

Collapse
 
gsharan2901 profile image
Sharan Gudimalla

Exactly, so I remember the opposite way XD. I used to do it in school tooπŸ˜‚

Collapse
 
robinpokorny profile image
Robin Pokorny • Edited on

To add one more reason why for..in is bad for arrays is that it skips gaps in sparse arrays:

const arr = ['a']
arr[5] = 'b'

for(const value of arr) {
  console.log(value);
}
// -> a
// -> undefined
// -> undefined
// -> undefined
// -> undefined
// -> b

for(const key in arr) {
  console.log(arr[key]);
}
// -> a
// -> b
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bradtaniguchi profile image
Brad

I used to get these mixed up all the time. Then I came up with a funny/simple saying.

"Use for...in if you want to be in trouble"

The most common use-case is to iterate over an array of things within an Array, where you'd want for...of, so using for...in would give you the "keys", or numbers which can create confusion.

You don't want to be "in" trouble, so don't use for...in. Hope that helps with remembering :D

Collapse
 
lazylad profile image
Tathagat

I have recently used for of to iterate over array and element of array were to passed to a async function as parameter and I need to hold the execution of loop util async function gets resolved I tried many things but at the end for of loop work in this case.

Collapse
 
imiahazel profile image
Imia Hazel

Thanks for the brilliant tutorial. It helped me a lot.

Collapse
 
swastikyadav profile image
Swastik Yadav Author

Thanks for your kind words Imia. It means a lot to me. 😊

Collapse
 
imiahazel profile image
Imia Hazel

You did really awesome :)

Collapse
 
nanythery profile image
Nadine M. ThΓͺry

Very useful article, thank you!

Collapse
 
swastikyadav profile image
Swastik Yadav Author

I am glad that you found this useful.

Collapse
 
princezakabdull profile image
Engnr. Zaks

I seems to always get it though πŸ˜‚

Collapse
 
bhaskerath profile image
Bhaskar A

Nice

Collapse
 
bogdanbatsenko profile image
bogdanbatsenko

Thanx. Nice and clean explanation

Collapse
 
swastikyadav profile image
Swastik Yadav Author

Glad, that this helped. πŸ˜ƒ

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.