Back to Basics: Loops in JavaScript
Tags: javascript, beginners, technicalinterviews, loops
Published: 2021-01-13 14:16:35

This series discusses the building blocks of JavaScript. Whether you're new to the language, you're preparing for a technical interview, or you're hoping to brush up on some key JS concepts, this series is for you.

The first installment in this series is about loops:
- [What is a loop?](#what-is-a-loop)
  - [Infinite loops](#infinite-loops)
- [While loops](#while-loops)
- [For loops](#for-loops)
- [Do...while loops](#dowhile-loops)
- [For...in loops](#forin-loops)
- [For...of loops](#forof-loops)
- [Resources](#resources)


## What is a loop?
A loop tells your program to repeatedly do a certain action. The number of times your program should do that action depends on the conditions that you set.

In non-programming terms, let's say you're giving your friend directions to your house. They call you and say that they're on your street, but they don't know which house is yours. You tell them, "keep walking north until you reach the yellow house on the corner". In this statement, "until you reach the yellow house on the corner" is the condition you've set for your friend. They will continue to walk north *until* they get to that house, at which point they'll *stop* walking.

![Your friend starts on the same street as your house, and walks north until they reach your house](https://dev-to-uploads.s3.amazonaws.com/i/t5vegk97wyl77f2s9m6w.png)

What would happen if you didn't give your friend the condition? In other words, what would happen if you just said to your friend, "keep walking north"? Your friend would never know when to stop. They would keep walking north way past your house. You can't blame your friend for not finding your house, since you never told them when to stop.

![Your friend has walked past your house, and is still going north](https://dev-to-uploads.s3.amazonaws.com/i/hdlk4aobxjpfdy1pme7o.png)

This non-programming example illustrates one of the most common issues people encounter when working with loops: <a id="infinite-loops"/>**the infinite loop**</a>. If you don't tell your loop when to stop, the loop will keep going forever. Importantly, if you tell your loop when to stop, but that stopping point could never actually be reached, that also is an infinite loop. Using the same example, let's say you told your friend "keep walking north until you reach the pink house on the corner". Your friend keeps walking north, but no matter how far they walk, they never find a pink house on the corner. Even though you gave your friend an ending point, they never could reach that ending point, so they would (theoretically) keep walking forever.

When working with loops, it's very important that you say when the loop should stop running, and that that ending point can actually be reached.

## While loops
One of the most popular loops is a **while loop**. A `while` loop is structured like the following:

```
while (condition) {
    statement
}
```

Before the statement is executed, `condition` is tested. If it evaluates to `true`, then the statement is executed. As long as `condition` is `true`, the statement continues to execute. When `condition` becomes `false`, the statement stops executing.

For example, let's say you have a variable called `e`, which starts out by equaling `0`. You want `e` to keep *incrementing* (or increasing by 1) as long as `e` is less than `4`.

```javascript
let e = 0;
while (e < 4) {
    e++;
}
```

Here is a table breaking down what's going on in the above loop:

| `e` | `e < 4` | Loop executes? |
| -- | -- | -- |
| 0 | true | yes |
| 1 | true | yes |
| 2 | true | yes |
| 3 | true | yes |
| 4 | false | no |

As long as `e < 4` is `true`, the loop executes. When it becomes `false`, it does not execute.

It's very easy to accidentally write an infinite loop when working with `while` loops. For example, if the condition from the above example was `e >= 0`, then the loop will infinitely execute. `e` starts at `0`, which means the condition is `true`, and keeps getting bigger, which means the condition will always evaluate to `true`:

```javascript
//Infinite loop
let e = 0;
while (e >= 0) {
    e++;
}
```

## For loops
Another loop that's widely used is the **for loop**. A `for` loop is structured like the following:

```
for (initialExpression; conditionExpression; incrementExpression) {
    statement
}
```
The `initialExpression` is the first thing that runs. Any variable created in this expression is *scoped* to the loop (meaning that you cannot refer to this variable from outside of the loop). The `initialExpression` is usually where a counter is initialized.

The `conditionExpression` is then evaluated for being either `true` or `false`. If it's `true`, then the statement executes. If it's `false`, the statement does not execute, and the `for` loop terminates. If no `conditionExpression` is listed, then the condition is automatically `true`.

The `incrementExpression` runs *after* the statement executes. Just as the `initialExpression` usually initializes a counter in a `for` loop, the `incrementExpression` usually increments that counter. However, the expression also can *decrement* the counter (or decrease by 1). At this point, the `conditionExpression` is evaluated again, and if it's still `true`, then the `for` loop continues to execute.

For example, let's create a `for` loop that logs the phrase "I can count to X" to the console, where `X` is a number starting at `1`, and going to `5`. We start by initializing a variable in the `initialExpression` with `let i = 1`. Then, we set the `conditionExpression` to `i <= 5`. This means that the statement will continue to run as long as `i` is less than or equal to `5`. Finally, we want to increase `i` by 1 each time the loop executes, so `incrementExpression` is `i++`. **Note:** it's important that each of the expressions is separated by a semicolon, `;`.

```javascript
for (let i = 1; i <= 5; i++) {
    console.log("I can count to " + i)
}
```

Here is a table breaking down what's going on in the above loop:

| `i` | `i <= 5` | Statement logged |
| -- | -- | -- |
| 1 | true | "I can count to 1" |
| 2 | true | "I can count to 2" |
| 3 | true | "I can count to 3" |
| 4 | true | "I can count to 4" |
| 5 | true | "I can count to 5" |
| 6 | false |  |

Infinite loops also happen with `for` loops. One example of an infinite loop would be using the same example above, but changing the third expression to be `i--`. `i--` means that `i` keeps decreasing, so `i` will start at `1`, then become `0`, then `-1`, and so on. All the while, `i <=5` will continue to evaluate to `true`, because `i` will always be less than or equal to `5`.

```javascript
//Infinite loop
for (let i = 1; i <= 5; i--) {
    console.log("I can count to " + i)
}
```

## Do...while loops
The **do...while loop** is very similar to the `while` loop. A `do...while` loop is structured like the following:

```
do {
    statement
} while (condition);
```

The first thing that happens in this loop is the statement is executed. Once that happens, `condition` is checked. If `condition` evaluates to `true`, the statement executes again. The statement keeps executing until `condition` evaluates to `false`. The major difference between the `do...while` loop and the `while` loop is that the statement will always be executed **at least once**.

For example, let's initialize a variable called `booksRead` to equal `10`. We want to log "I read X books this year" to the console, where `X` is the value of `booksRead`. We'll then set the condition to be `booksRead < 14`. **Note:** in the below example, I use *string interpolation* when console logging the number of books read this year. String interpolation is done by using [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) in JavaScript.

```javascript
let booksRead = 10;
do {
    console.log(`I read ${booksRead} books this year`);
    booksRead++;
} while (booksRead < 14);
```

Here is a table breaking down what's going on in the above loop:

| `booksRead` | Statement logged | `booksRead < 14` |
| -- | -- | -- |
| 10 | "I read 10 books this year" | true |
| 11 | "I read 11 books this year" | true |
| 12 | "I read 12 books this year" | true |
| 13 | "I read 13 books this year" | true |
| 14 |  | false |

One way you can create an infinite loop when working with `do...while` loops is if you don't increment the variable that you're checking in the condition. Using the same example as above, if you never increment `booksRead`, then `booksRead` stays at `10` forever, which means the condition, `booksRead < 14`, will always be `true`.

```javascript
//Infinite loop
let booksRead = 10;
do {
    console.log(`I read ${booksRead} books this year`);
} while (booksRead < 14);
```

## For...in loops
A **for...in loop** is used with an object in JavaScript. It's structured like the following:

```
for (variable in object) {
    statement
}
```
A `for...in` loop iterates a variable over each property (or key) of an object. For each property, the statement is executed. The loop enables you to access each property of an object without knowing the name of the property. `for...in` loops iterate over the object's properties in an arbitrary order. Therefore, according to [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in), "it is best **not to add, modify, or remove properties** from the object during iteration, other than the property currently being visited". You also should **not use for...in loops with arrays**.

For example, let's say you had an object that listed each meal you had that day, and you wanted to console log everything you ate. The object is called `foodIAte`. Using a `for...in` loop, you can list the name of each meal, as well as what you ate for that meal.

```javascript
const foodIAte = {
    breakfast: 'eggs',
    lunch: 'salad',
    dinner: 'pizza'
};

for(const meal in foodIAte) {
  console.log(`For ${meal}, I ate ${foodIAte[meal]}.`);
};
```

Here is a table breaking down what's going on in the above loop:

| `meal` | `foodIAte[meal]` | Statement logged |
| -- | -- | -- |
| breakfast | eggs | For breakfast, I ate eggs. |
| lunch | salad | For lunch, I ate salad. | 
| dinner | pizza | For dinner, I ate pizza. |


## For...of loops
The last loop is the **for...of loop**. The `for...of` loop can be used with *iterable objects*, which includes arrays, maps, sets, strings, [and more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). It's structured like the following:

```
for (variable of iterableObject) {
    statement
}
```

The `for...of` loop iterates over `iterableObject`, and a statement is executed for the value of each property in `iterableObject`. While `for...in` loops iterate over the property *name*, `for...of` loops iterate over the property *value*.

For example, let's say you have an array, and want to console log each value of the array:

```javascript
const array = [5, 10, 15];
for (const value of array) {
    console.log(value);
}
```

The above loop would console log `5`, `10`, `15`.

Let's say you have a string, and want to console log each value of the string:

```javascript
const string = "cat";
for (const value of string) {
    console.log(value);
}
```

The above loop would console log `c`, `a`, `t`.

---

Please let me know in the comments if you have any questions or other ways of thinking about loops in JavaScript.

### Resources:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
- https://www.w3schools.com/js/js_loop_for.asp
- https://www.freecodecamp.org/news/javascript-loops-explained-for-loop-for/
- https://www.javascripttutorial.net/javascript-for-in/