Javascript loops: for vs forEach vs for.. in vs for.. of

Johnny Simpson - Nov 6 '22 - - Dev Community

There are quite a few ways in Javascript to loop through an array of items or any other iterable item in Javascript. You may have seen them:

  • arr.forEach()
  • for(let item of arr)
  • for(let item in arr)
  • for(let item = 0; item < arr.length; ++item)

This may seem like a lot of ways to accomplish the same thing, but they all have their own nuance. For any of these to work, the item in question also needs to be iterable. So while they will work with things like Map, Set, and Arrays, they will not work with Objects. Strings are also iterable.

Since there are so many ways, it can be confusing when to use forEach, in or of in Javascript. Today, let's understand in detail what each of these does, and when to use them.

The forEach Method

forEach is a tool many are drawn to because linguistically it makes sense. arr.forEach sounds right, and it provides an easy callback function to do whatever we want to do with each item in an iterable like an array:

let x = [ 1, 2, 3, 4, 5 ];
x.forEach((item, index) => {
    x[index] += 1;
});
console.log(x); // [ 2, 3, 4, 5, 6 ];
Enter fullscreen mode Exit fullscreen mode

However, forEach is a method - which means that it only appears on certain data types in Javascript. For example, all Arrays have a forEach method, and so do Maps and Sets - but despite being iterable, Strings do not. Notably, DOM elements didn't have forEach until recently. So while it is reliably available in many different circumstances. It is also much slower than a regular old for loop.

Beyond that, forEach does not really work with async methods like await or promises either. In circumstances where you need to use promises or await, its best to avoid it and use for loops instead.

While forEach is definitely an easy way to iterate over an array, it's not always the best.

 Using for loops on iterables

There are three types of for loops to run over iterables in Javascript:

  • for(let item of arr)
  • for(let item in arr)
  • for(let item = 0; item < arr.length; ++item)

For those new to the language, the syntax can seem quite confusing. When Javascript first started out, the original for loop everyone used was the last one listed above:

let x = [ 1, 2, 3, 4, 5 ];
for(let i = 0; i < x.length; ++i) {
    console.log(x[i]); // 1.. 2.. 3.. 4.. 5
}
Enter fullscreen mode Exit fullscreen mode

This is an easy, straight forward way of accessing the index of an array. Here, i starts at 0, and increases for each item in the array x. Therefore, i reliably represents the index for each item, and thus writing x[i] will let us do something with each item in the array.

Since then, two new types of for loop have been introduced - in and of.

in vs of in Javascript for loops

The best way to understand in and of in Javascript for loops is that in is a simplification of the for loop we just looked at. It is an easier way to access the index in an array.

Meanwhile, of is an easy way to represent the array item itself. Let's look at a quick example. Here, we get the index of each item in our array using in:

let x = [ 5, 10, 15, 20, 25, 30 ];
for(let i in x) {
    console.log(i); // 0.. 1.. 2.. 3.. 4.. 5
}
Enter fullscreen mode Exit fullscreen mode

Meanwhile, if we use of it gets the actual value of the array item:

let x = [ 5, 10, 15, 20, 25, 30 ];
for(let i of x) {
    console.log(i); // 5.. 10.. 15.. 20.. 25.. 30
}
Enter fullscreen mode Exit fullscreen mode

So while in basically simplifies for(let i = 0; i < x.length; ++i), of actually gives us new functionality to access the array contents itself. This can be particularly useful if we have objects in our arrays:

let x = [ { name: "John" }, { name: "Jacob" }, { name: "Jingleheimer" }, { name: "Schmidt" }]
for(let item of x) {
    console.log(item.name); // John.. Jacob.. Jingleheimer.. Schmidt
}
Enter fullscreen mode Exit fullscreen mode

It should also be noted that for other iterables like Maps and Sets, for.. of will return an array of both key and value, while in will not work. For example:

let myMap = new Map();
myMap.set('x', 5);

for(let x of myMap) {
    console.log(x); // [ 'x', 5 ]
}

for(let x in myMap) {
    console.log(x); // does not console log anything
}
Enter fullscreen mode Exit fullscreen mode

To learn more about Maps and Sets you can read my detailed Javascript Map guide and Javascript Set guide here.

Iterating through objects

While objects themselves aren't iterable in Javascript, they can be converted to iterables by using Object.keys() or Object.values(). This converts an object in an array of either its keys or values, which can then be iterated on:

let obj = { name: "John", secondName: "Jacob", age: 154 };
let iterableKeys = Object.keys(obj);
for(let item of iterableKeys) {
    console.log(item); // name.. secondName.. age
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

That about covers everything you need to know. In summary:

  • forEach is a method that is attached to most iterable items in Javascript, with a few exceptions. It is callback based, usually doesn't work with promises, and is slower than a traditional for loop.
  • for loops are available on every iterable object, and it used to be for(let i = 0; i < x.length; ++i) was the only format anyone used.
  • for.. in was introduced to simplify for(let i = 0; i < x.length; ++i) to for(let i in x).
  • Finally, we gained the ability to access the values of each item in the iterable rather than just the key, using for.. of.

I hope you've enjoyed this guide, and have a better idea of when to use in, forEach, and of in Javascript.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .