In JavaScript and TypeScript, array iteration is incredibly common. Many developers reach for the familiar .forEach method due to its simplicity.
However, a powerful and more flexible alternative exists: the for...of loop. 🔮 This article dives deep into why you should consider making the switch and how for...of can make your coding more efficient and expressive.
.forEach vs. for...of: A Quick Comparison 🔧
Let's quickly recap how these two methods work with simple examples:
.forEach Method
const fruits = ['apple', 'banana', 'cherry'];
fruits.forEach(fruit => {
console.log(fruit);
});.forEach iterates directly over an array, executing a provided callback function for each element.
for...of Loop
const fruits = ['apple', 'banana', 'cherry'];
for (const fruit of fruits) {
console.log(fruit);
}Introduced in ES6, for...of offers a more flexible way to iterate over iterables, including arrays.
Why Make the Switch? The Power of for...of 🌼
While .forEach is convenient, for...of provides advantages that can enhance your coding.
1. Superior Asynchronous Handling
for...of shines when dealing with asynchronous operations. .forEach doesn't play nicely with async/await because it doesn't natively handle promises.
Example: Asynchronous Code with .forEach (Problematic)
const fetchData = async (url: string) => {
const response = await fetch(url);
return response.json();
};
const urls = ['url1', 'url2', 'url3'];
urls.forEach(async url => { // Potential for race conditions!
const data = await fetchData(url);
console.log(data);
});This code won't wait for each fetch to complete before starting the next one, potentially leading to race conditions.
Example: Asynchronous Code with for...of (Correct)
const fetchData = async (url: string) => {
const response = await fetch(url);
return response.json();
};
const urls = ['url1', 'url2', 'url3'];
(async function () {
for (const url of urls) {
const data = await fetchData(url);
console.log(data);
}
})()
Here, each fetch waits for the previous one to finish, ensuring sequential execution and more predictable behavior.
2. Embrace break and continue
.forEach lacks support for break and continue statements, limiting its flexibility in certain scenarios.
Example: Terminating a Loop with for...of
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
if (number === 3) {
break;
}
console.log(number); // Outputs: 1, 2
}Example: Skipping Iterations with for...of
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
if (number === 3) {
continue;
}
console.log(number); // Outputs: 1, 2, 4, 5
}These features make for...of vastly more powerful.
3. Enhanced Readability and Maintainability
for...of often leads to more readable code, especially when dealing with nested structures or complex operations. 👈
Example: Nested Iteration with .forEach
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
matrix.forEach(row => {
row.forEach(cell => {
console.log(cell);
});
});Example: Nested Iteration with for...of
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (const row of matrix) {
for (const cell of row) {
console.log(cell);
}
}The for...of version is often more concise and easier to follow, which improves maintainability.
Level Up Your Code: Advanced for...of Techniques ✨
for...of isn't just for arrays—it works with any iterable object, including generators. Here are a few advanced uses:
Iterating Over Objects with Object.entries
const user = {
name: 'Alice',
age: 30,
job: 'developer'
};
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}Combining with Generator Functions
function* generateNumbers() {
yield 1;
yield 2;
yield 3;
}
for (const number of generateNumbers()) {
console.log(number);
}Simplifying Iteration with Destructuring
const users = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 }
];
for (const { name, age } of users) {
console.log(`${name} is ${age} years old`);
}Conclusion
Switching from .forEach to for...of can bring numerous advantages to your JavaScript/TypeScript projects, including robust asynchronous code handling, more control over loop execution, and enhanced readability.
Give for...of a try in your next project—it might become your new array iteration go-to! Happy coding!
In Plain English 🚀
Thank you for being a part of the In Plain English community! Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: X | LinkedIn | YouTube | Discord | Newsletter
- Visit our other platforms: CoFeed | Differ
- More content at PlainEnglish.io