Repeating a treatment over a list is the most common operation in any program: adding up amounts, printing rows, transforming data received from an interface.
JavaScript offers three for loops, and they do not walk the same thing. Picking the wrong one raises no error, only an unexpected result, which takes longer to diagnose.
Definition
The historic form holds three expressions separated by semicolons: an initialization, a condition checked before each turn, and an update run after each turn.
const carts = [12, 30, 8];
let total = 0;
for (let i = 0; i < carts.length; i++) {
total += carts[i];
}
console.log(total); // 50Declaring the counter with let rather than var gives it a fresh binding on every turn, which matters as soon as a function is created inside the loop. This form also remains the only one able to step by two, run backwards, or stop before the end of an array.
for...of, the form to write by default
When the counter only exists to reach the items, it is noise. for...of walks the values directly, with no index and no risk of running past the length.
const carts = [12, 30, 8];
let total = 0;
for (const amount of carts) {
total += amount;
}
console.log(total); // 50It works on anything iterable: an Array, a string, a Map, a Set. And unlike the array methods, it accepts break and continue, which makes it essential as soon as a walk has to stop early.
for...in walks the keys, not the values
for...in enumerates the property names of an object. It is the right form for an Object, and exactly the one to avoid on an array.
const client = { name: "Alice", city: "Lyon" };
for (const key in client) {
console.log(key, client[key]); // name Alice, then city Lyon
}On an array, for...in hands back the indexes as strings, so an addition concatenates them instead of summing them. It also surfaces properties added to the object, including ones nobody knew were there.
Frequently asked questions
Should for or forEach be preferred?
Array.forEach() reads well when the treatment applies to every item without exception. As soon as the walk has to stop midway, the for loop takes the lead again, because no return placed in the forEach callback interrupts the walk. To produce a new list rather than act, Array.filter() or Array.reduce() state the intent more clearly than a loop.
How do you walk an object cleanly?
By turning it into an array of pairs with Object.entries() first, then walking it with for...of and a Destructuring. The key and the value are then named from the first line, instead of forcing an indexed access at every use.
const stock = { apple: 3, pear: 0 };
for (const [product, quantity] of Object.entries(stock)) {
console.log(product, quantity);
}How do you leave a nested loop?
A break leaves only the loop directly containing it. To leave both at once, put a label in front of the outer loop and write break followed by that name. The often more readable option moves both loops into a function and leaves through return. Our JavaScript course works through these trade-offs on real data walks.