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 ];
However, forEach
is a method - which means that it only appears on certain data types in Javascript. For example, all Array
s have a forEach
method, and so do Map
s and Set
s - but despite being iterable, String
s 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
}
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
}
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
}
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
}
It should also be noted that for other iterables like Map
s and Set
s, 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
}
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
}
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 befor(let i = 0; i < x.length; ++i)
was the only format anyone used. -
for.. in
was introduced to simplifyfor(let i = 0; i < x.length; ++i)
tofor(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.