Thefor...of loopis the most recent addition to the family of for loops in JavaScript.
It combines the strengths of its siblings, thefor loopand thefor...in loop, to loop over any type of data that isiterable(meaning it follows theiterable protocolwhich we'll look at in lesson 3). By default, this includes the data types String, Array, Map, and Set—notably absent from this list is theObject
data type (i.e.{}
). Objects are not iterable, by default.
Before we look at the for...of loop, let’s first take a quick look at the other for loops to see where they have weaknesses.
The for loop
The for loop is obviously the most common type of loop there is, so this should be a quick refresher.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0; i < digits.length; i++) {
console.log(digits[i]);
}
Prints:
0
1
2
3
4
5
6
7
8
9
Really the biggest downside of a for loop is having to keep track of the counter and exit condition.
In this example, we’re using the variablei
as a counter to keep track of the loop and to access values in the array. We’re also usingdigits.length
to determine the exit condition for the loop. If you just glance at this code, it can sometimes be confusing exactly what’s happening; especially for beginners.
While for loops certainly have an advantage when looping through arrays, some data is not structured like an array, so a for loop isn’t always an option.
The for...in loop
The for...in loop improves upon the weaknesses of the for loop by eliminating the counting logic and exit condition.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
Prints:
0
1
2
3
4
5
6
7
8
9
But, you still have to deal with the issue of using an index to access the values of the array, and that stinks; it almost makes it more confusing than before.
Also, the for...in loop can get you into big trouble when you need to add an extra method to an array (or another object). Because for...in loops loop over all enumerable properties, this means if you add any additional properties to the array's prototype, then those properties will also appear in the loop.
Array.prototype.decimalfy = function() {
for (let i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2);
}
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
Prints:
0
1
2
3
4
5
6
7
8
9
function() {
for (let i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2);
}
}
Gross! This is why for...in loops are discouraged when looping over arrays.
NOTE:The forEach loop is another type of for loop in JavaScript. However,
forEach()
is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.
Finally, we have the mighty for...of loop.
For...of loop
The for...of loop is used to loop over any type of data that is iterable.
You write a for...of loop almost exactly like you would write a for...in loop, except you swap outin
withof
and you can drop the index.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
Prints:
0
1
2
3
4
5
6
7
8
9
This makes the for...of loop the most concise version of all the for loops.
TIP:It’s good practice to use plural names for objects that are collections of values. That way, when you loop over the collection, you can use the singular version of the name when referencing individual values in the collection. For example,
for (const button of buttons) {...}
.
Progression from the for loop to the for...in loop to the for...of loop.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0; i < digits.length; i++) {
console.log(digits[i]);
}
>>>
for (let index in digits) {
console.log(digits[index]);
}
>>>
for (let digit of digits) {
console.log(digit);
}
But wait, there’s more! The for...of loop also has some additional benefits that fix the weaknesses of the for and for...in loops.
You can stop or break a for...of loop at anytime.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
if (digit % 2 === 0) {
continue;
}
console.log(digit);
}
Prints:
1
3
5
7
9
And you don’t have to worry about adding new properties to objects. The for...of loop will only loop over the values in the object.
Array.prototype.decimalfy = function() {
for (i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2);
}
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
Prints:
0
1
2
3
4
5
6
7
8
9
Directions:
Write afor...of
loop that:
- loops through each day in the
days
array - capitalizes the first letter of the day
- and prints the day out to the console
Your code should log the following to the console:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
/*
* Programming Quiz: Writing a For...of Loop (1-4)
*/
const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
// your code goes here
for (const day of days) {
console.log(day[0].toUpperCase() + day.substr(1));
}