The for loops in JS
Tags: javascript, arrays, codenewbie, 100daysofcode
Published: 2021-03-25 08:03:21

There are several different ways to loop through elements in an array. Most likely, you will see `for`, `forEach`, `for..in`, and `for..of`. These 4 (pseudo pun intended here) are often confused and that's what we are going to fix 💪

In many older codebases and code examples online, you will see the ubiquitous `for` loop used to iterate over an array. The typical setup initializes a variable `i` to 0 (because we want to start with the zeroth element). The second statement defines how many times the loop will run, most often you'll iterate over every element in the array - so `i < array.length`. And the 3rd statement increasing `i` on every pass. This allows us to access each element in the array by its index and perform something.

Here, we are just logging the score to the console:

```js
const scores = [82, 89, 90, 94, 81];

for (let i = 0; i < scores.length; i++) {
  console.log(scores[i]);
}

> 82
> 89
> 90
> 94
> 81
```

In more modern codebases, however, you will see a mix of `forEach`, `for..in`, and `for..of`. The most common scenario you will encounter is that you want to iterate over every element in the array and execute something using that element. So which do you choose?

Let's start with a more concise version of what the `for` loop gives us. With `for..of`, we are able to quickly access each element without having to keep track of the index or worry about incrementing/decrementing the index.

```js
const scores = [82, 89, 90, 94, 81];

for (const score of scores) {
  console.log(score);
}

> 82
> 89
> 90
> 94
> 81
```

With `forEach`, you have access to the index of the current element being iterated over, the element value, and the array itself. Sounds great, right? Well it is, and proponents of the [Functional Programming](https://eloquentjavascript.net/1st_edition/chapter6.html) paradigm greatly prefer this method of looping. `forEach` expects a synchronous function, so be aware of that when using `async/await` with it. You can’t use `await` in the `body` of this kind of loop and you can’t leave a `forEach` loop early. In `for` loops, we can use `break`. Do be aware of any mutations you may be making within the loop (if you use a return).

```js
const scores = [82, 89, 90, 94, 81];

scores.forEach((score) => console.log(score));

> 82
> 89
> 90
> 94
> 81
```

The `for..in` loop is meant to be used with objects, not arrays. So if you use it with an array, you will likely get some unexpected output. This is because `for..in` is iterating of the [enumerable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) of the object (at the end of the day, our arrays are objects).

```js
const scores = [82, 89, 90, 94, 81];

for (const score in scores) {
  console.log(score);
}

> 0
> 1
> 2
> 3
> 4
```

### Here's a basic rundown of when to use for..of vs for..in:

![for loops](https://www.speek.design/for..of-for..in.png)

---

Now that we have a better idea of what the different types of `for` loops do, let's dive into some exercises to test our newfound knowledge!

In your browser, open up the developer tools to the console tab and console log the scores that are less than 90 using the classic `for` loop (not `for..in` or `forEach`):

```js
const scores = [82, 89, 90, 94, 81];
// for() {} loop goes here
```

Now, console log the scores that are less than 90 using the `forEach` loop:

```js
const scores = [82, 89, 90, 94, 81];
// forEach loop goes here
```

Next, console log the scores that are less than 90 using the `for..of` loop:

```js
const scores = [82, 89, 90, 94, 81];
// for..of loop goes here
```

Lastly, console log the index of the scores that are 90 or greater (≥ 90) using the `forEach` loop. Hint: the [second argument is the index](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) `apples.forEach((apple, index) => { console.log(index) })`:

```js
const scores = [82, 89, 90, 94, 81];
// for loop goes here
```

### Final note on iterating over arrays

Remember when I told you that `forEach` is expecting a synchronous function? Well we can also use that to our advantage when we don't want to explicitly iterate over an array's elements one-by-one. For longer running loops, you'll see the benefit of using `forEach` vs reaching for `for..of`

Let's take our scores and loop over them using `forEach`. If we pretend that we have some longer running code in there using `async/await`, you'll notice that the `console.log(score)` doesn't wait for it. This can be a useful tool to take advantage.

```js
const scores = [82, 89, 90, 94, 81];
scores.forEach(async (score) => {
  await new Promise((resolve) => setTimeout(resolve, 500)); //fake long running code
  console.log(score);
});
```

To contrast, `for..of` will wait for that longer running code to finish before moving on to our `console.log(score)`:

```js
const scores = [82, 89, 90, 94, 81];
for (let score of scores) {
  await new Promise((resolve) => setTimeout(resolve, 500)); //fake long running code
  console.log(score);
}
```

These are basic examples of running in sequence versus running in parallel. If you're needing to run in sequence, reach for `for..of` in this case. If you are able to run in parallel (you don't need to wait for that longer running process), try using `forEach` instead.

For more information on the asynchronous version of `for..of`, see this post on [`for await..of`](https://2ality.com/2016/10/asynchronous-iteration.html#for-await-of) 👀

### To dive deeper into arrays, check out my course [Working with Arrays](https://speek.design/arrays) 🔥