Lesson Wednesday

In general, we should use `Array.prototype.forEach()` when we want to loop through every element in an array. If we are using a loop that isn't iterating through an array, we can't use `Array.prototype.forEach()` for that loop - that's pretty obvious.

However, sometimes we can't use `Array.prototype.forEach()` when we are looping through an array. Specifically, if we want to stop the loop, we can't use `Array.prototype.forEach()`. Looping through every element in an array is a requirement of `Array.prototype.forEach()`.

Let's look at an example when this might matter. Let's say we have a series of arrays that hold sequences of DNA. These sequences can potentially be very long - and we want to stop searching an array as soon as we find a pattern. We'll call that pattern "A" (to represent a specific DNA sequence). We'll also add a few other letters to represent other DNA sequences. A biologist won't be impressed by our approximation... but we are programmers and this is a programming example!

Here's our sample "sequence":

``````const dnaSequence = ["X", "A", "Y", "M", "D"];
``````

In this example, `"A"` is the second element in this array. We could use an `Array.prototype.forEach()` loop to flag the sequence if it includes `"A"`. Here's the code:

``````let dnaFlag = false;
const dnaSequence = ["X", "A", "Y", "M", "D"];
dnaSequence.forEach(function(element) {
if (element === "A") {
dnaFlag = true;
};
console.log("Looped!")
});
dnaFlag;
``````

In the code above, when an iteration through the loop finds a match with `"A"`, it will switch the `dnaFlag` boolean to `true`. Using boolean flags in this manner is very common in coding.

Note, however, that the second character in our array matched the letter `"A"`. What if our array were a million elements long? (DNA sequences can be very complex.) Our loop needs to loop through all million elements - even though we really only need to do two iterations of the loop to switch `dnaFlag` to `true`. This would be horribly inefficient. We've added a `console.log("Looped!")` to show how many times this loop runs.

In order to break out of loop, we need to use the `break;` keyword. This keyword does exactly what it sounds like: stops a loop.

What happens if we try to add a `break;` statement to the loop above?

``````let dnaFlag = false;
const dnaSequence = ["X", "A", "Y", "M", "D"];
dnaSequence.forEach(function(element) {
if (element === "A") {
dnaFlag = true;
break;
};
});
dnaFlag;
``````

We'll get the following error: `Uncaught SyntaxError: Illegal break statement`. In short, we can't break out of this kind of loop.

However, we can use a break statement with a `for` loop. Try the following in the console:

``````let dnaFlag = false;
const dnaSequence = ["X", "A", "Y", "M", "D"];
for (let i = 0; i < dnaSequence.length; i +=1) {
if (dnaSequence[i] === "A") {
dnaFlag = true;
break;
};
console.log("Looped!");
}
dnaFlag;
``````

We've added a `console.log("Looped!")` to this code, too - and you'll see it only triggers once. The second time through the loop, the condition is met and the loop breaks due to the `break;` keyword.

There's something that's not so great about the code above. As of now, the `dnaFlag` variable is globally scoped. In an ideal world, we'd wrap this all in a function. Let's do this now, not just because it's better code but also so we can see what happens when we try to `return` out of both a `for` loop and an `Array.prototype.forEach()` loop.

We'll start by wrapping the `for` loop in a function called `dnaPatternDetector`:

``````function dnaPatternDetector(dnaSequence, pattern) {
for (let i = 0; i < dnaSequence.length; i +=1) {
if (dnaSequence[i] === pattern) {
return true;
};
console.log("Looped!");
}
return false;
}
``````

We've done a bunch of things to refactor this code. Our function takes two parameters. The `dnaSequence` is an array of characters. The pattern is the character we are looking for (we are looking for `"A"`).

We actually don't need to use the `dnaFlag` anymore. If the pattern is met (`dnaSequence[i] === pattern`), then the loop will stop running and our function will return `true`. If the pattern is never met, our loop will complete and the final part of our function will be reached: `return false;`.

Let's try the following out in the console. First, some variables - a `sequence` variable that includes an array and two variables for patterns: `pattern1` and `pattern2`:

``````const sequence = ["X", "A", "Y", "M", "D"];
const pattern1 = "A";
const pattern2 = "Z";
``````

Next, we'll also need to add our `dnaPatternDetector()` function in the console as well.

Finally, try this out:

``````dnaPatternDetector(sequence, pattern1);
``````

We'll see that the function returns `true` - exactly what we'd expect because `sequence` includes `"A"`. We also see that it only hits the `console.log("Looped!")` statement once. `return` has the same effect as the `break;` statement here - however, it doesn't just break us out of the loop, it returns from the function.

Now try out the second pattern, which is a character that's not included in `sequence`:

``````dnaPatternDetector(sequence, pattern2);
``````

Our loop iterates through every character in the array and never finds the character `"Z"`. The loop completes (so "Looped!" is printed to the screen five times). This is the only way the final part of the code can be reached: `return false`. The function returns false.

A function that actually checks DNA sequences would probably be quite a bit more complicated than this example. However, this does show a potential use case for when we'd want to break out of a loop - either with a `break;` or a `return` statement. This same function wouldn't work as intended with an `Array.prototype.forEach()` loop - if we try to put a `return` statement inside the loop, we'll get an error. The rules for `Array.prototype.forEach()` loops are strict - we must iterate through every element in the array - we can't break or return from it.

To summarize, you should favor `Array.prototype.forEach()` loops over `for` loops except in the following cases:

• You're not looping through an array. `Array.prototype.forEach()` can only be used with arrays.
• You need to break out of the loop - either with `break;` or a `return` statement.

We can add one more case just for the sake of practice:

• You should favor `for` loops even for looping through every element in an array until you understand exactly how they work. They are a cornerstone of JavaScript and it's essential to understand them even if you'll mostly use other types of loops in the future.

In the next lesson, we'll make changes to our text analyzer application. Both will be situations where a `for` loop will serve our purposes better.

You can use any kind of loop you want for this section's independent project. The project prompt can be solved with `Array.prototype.forEach()` but you are welcome to use `for` (or another kind of loop you learn later in this section) as well.

## When to Use `for` Loops

• When we need to break out of the loop. For instance, we might want to break out of a loop when we verify that an array contains a result. Instead of looping through the rest of the array, we can use the `break;` or `return` keyword to end the loop.

• When we're not looping through an array. `Array.prototype.forEach()` only works with arrays. When we are using other data types, `for` loops can be more convenient.

Lesson 11 of 13
Last updated more than 3 months ago.