When to use a "for" loop vs forEach
Both the "for" loop and "forEach" loop serve different purposes and have their own strengths.
The forEach
approach is ideal in scenarios where you simply need to iterate over array items and perform an action without the need for complex control flow.
You can't access the forEach
method on things that are not arrays.
Simply put, the forEach
method is specifically designed to work with arrays and is not available for objects or other data types.
On the other hand, a "for" loop statement is preferred when there is a need for complex control flow, such as:
- Can run a loop without needing to work with arrays
- Early loop termination
- Modifying the loop counter
- There are a few other specific scenarios
Early loop termination
If you need to exit the loop based on a specific condition, a "for" loop offers more flexibility.
For example, imagine you're searching for an item inside an array:
//List of Unsafe Passwords
let unsafePasswords = [
"123456",
"123456789",
"12345",
"qwerty",
"password",
"12345678",
"111111",
"123123",
"1234567890",
"1234567",
"qwerty123",
"000000",
"1q2w3e",
"aa12345678",
"abc123",
"password1",
"1234",
"qwertyuiop",
"123321",
"password123"
];
const passwordStrength = document.querySelector(".password-strength");
passwordField.addEventListener("keyup", function (event) {
// Check if password exists in the unsafe list using a for loop
for (let i = 0; i < unsafePasswords.length; i++) {
if (passwordField.value === unsafePasswords[i]) {
passwordStrength.style.color = "red";
passwordStrength.textContent = "You're using an unsafe password";
break; // Exit loop after finding a match
}
}
});
Don't worry if you don't understand the above code. We will work on it in detail in an upcoming module.
For now, just understand that we are taking a password as input from a user and checking if the password entered exists inside the unsafePasswords
array or not.
If the password was indeed found inside the unsafePasswords
array, we are using the break
statement to exit the loop as soon as the target password is found, saving unnecessary iterations.
This break
functionality is not directly available in forEach
.
If you want to achieve the same logic by using forEach
, you have to use something called a "try/catch" statement:
passwordField.addEventListener("keyup", function (event) {
try {
unsafePasswords.forEach(function (unsafePassword) {
if (passwordField.value === unsafePassword) {
// Throw the unsafe password to signal a match
throw unsafePassword;
}
});
} catch (unsafePassword) {
// Handle the thrown unsafe password
passwordStrength.style.color = "red";
passwordStrength.textContent = "You're using an unsafe password: " + unsafePassword;
}
});
Again, don't worry if you don't understand the above code. We will work on it in detail in an upcoming module.
Anyway, the code with the "try/catch" statement and the forEach
method looks much more complicated when compared to achieving the same functionality with a simple "for" loop and the break
statement.
Modifying the loop counter
Sometimes, you might need to modify the loop counter variable within the loop itself.
While possible in forEach
with additional tricks, it's more straightforward with a "for" loop:
// Skipping even elements in an array
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
for (let i = 0; i < numbers.length; i += 2) {
console.log(numbers[i]);
}
So far, you have only seen about how to increment the loop counter by 1.
But in the above code, we are incrementing the loop counter by 2 to iterate only over odd-indexed items
This technique can be tedious to achieve within forEach
.
Although forEach
doesn't offer direct control over the loop like for
loops, you can achieve the same functionality of skipping even elements using a combination of forEach
and a conditional statement:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
numbers.forEach(function(number, index) {
// Check if index is even
if (index % 2 === 0) {
// Skip even elements by returning from the callback
return;
}
console.log(number); // Print only odd-indexed array items
});
Just like a "for" loop, the forEach()
have access to the current loop counter as an index
parameter.
Using the index
parameter, we can skip working with unnecessary items of an array.
Anyway, the above code looks much more complicated and takes more lines of code when compared to the "for" loop version:
// Skipping even elements in an array
let numbers = [1, 2, 3, 4, 5, 6, 7, 8];
for (let i = 0; i < numbers.length; i += 2) {
console.log(numbers[i]);
}
Isn't it?
So, as I always say, pick the right tool for the right job.
Don't increase the complexity of your code just because you prefer one tool over another.
At the end of the day, the best choice depends on the specific requirements of your code and the desired level of control for your loop.
That's all I wanted to convey about "for" loops and "forEach" loops for now.
We will learn all these snippets and other unexplored concepts in detail when their needs come in real-world projects.
In the next lesson, we will perform a small challenge, and after that, we will understand NodeLists and start building some real-world components like Tabs, Galleries, etc.