Javascript loops: for vs forEach vs for.. in vs for.. of
Tags: javascript, webdev, typescript, tutorial
Published: 2022-11-06 17:46:50

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](https://fjolt.com/article/javascript-map-data), [Set](https://fjolt.com/article/javascript-sets), 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:
```javascript
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](https://fjolt.com/article/javascript-multiple-elements-addeventlistener). 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:
```javascript
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`:
```javascript
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:
```javascript
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:
```javascript
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:
```javascript
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](https://fjolt.com/article/javascript-map-data) and [Javascript Set guide](https://fjolt.com/article/javascript-sets) 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:
```javascript
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 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.