Lesson 10 of 28
Repeating Work
for, for...of and while explained piece by piece — how to stop early with break, skip an item with continue, and know which loop fits which job.
You have three lesson titles to print. You could write three console.log
lines. Now imagine you have four hundred, and you do not know how many until
the program runs. That is the problem a loop solves: do this again, for each
thing, however many there turn out to be.
The for loop, one piece at a time
The for loop is the first line of code you will write with three separate
parts in it, and the parts are easier than they look.
for (let i = 0; i < 3; i++) {
console.log(i);
}
// 0
// 1
// 2Inside the brackets, separated by semicolons:
- The start —
let i = 0runs once, before anything else.iis a counter, and it begins at 0 because array indexes begin at 0. - The condition —
i < 3is checked before every pass. While it is true, the block runs. The moment it is false, the loop is over. - The step —
i++runs after each pass. It adds one to the counter, which is what eventually makes the condition false.
Leave out the step and the counter never changes, the condition stays true forever, and the page freezes. That is an infinite loop, and every programmer writes one eventually.
Paired with an array, the counter becomes an index:
const lessons = ["Functions", "Arrays", "Async"];
for (let i = 0; i < lessons.length; i++) {
console.log(i, lessons[i]);
}
// 0 "Functions"
// 1 "Arrays"
// 2 "Async"Note i < lessons.length and not i <= lessons.length. With three items the
valid indexes are 0, 1 and 2, so the loop must stop when i reaches 3. Using
<= gives you one extra pass that reads past the end and quietly returns
undefined. This mistake is common enough to have a name: an off-by-one error.
for...of, the friendlier default
Most of the time you do not care about the index at all. You just want each
item. for...of hands them to you directly:
const lessons = ["Functions", "Arrays", "Async"];
for (const title of lessons) {
console.log(title);
}
// "Functions"
// "Arrays"
// "Async"No counter, no length, no chance of an off-by-one error. Read it aloud and it
says what it does: for each title of lessons. Use for...of unless you
genuinely need the position number, in which case go back to the classic for.
while, when you cannot count in advance
A for loop suits "do this a known number of times". A while loop suits "keep
going until something changes", where you have no idea how many passes that
will take.
let credits = 10;
let lessonsBought = 0;
while (credits >= 3) {
credits -= 3;
lessonsBought++;
}
console.log(lessonsBought); // 3
console.log(credits); // 1The condition is checked before each pass, exactly like a for loop, but
nothing updates the counter for you. Something inside the block must eventually
make the condition false, or the loop never ends. When a while loop hangs,
that missing update is nearly always the reason.
break and continue
Two keywords change the flow mid-loop.
break stops the whole loop immediately:
const lessons = ["Functions", "Arrays", "Async"];
for (const title of lessons) {
if (title === "Arrays") {
console.log("Found it");
break; // nothing after this runs, and Async is never checked
}
}continue skips the rest of the current pass and moves to the next item:
const minutes = [8, 0, 12, 0, 9];
for (const value of minutes) {
if (value === 0) {
continue; // ignore the empty ones
}
console.log(value);
}
// 8
// 12
// 9The short version: break leaves the building, continue skips to the next
person in the queue.
Looping over an object
for...of does not work on plain objects, because an object has no order to
walk through. You have two options instead.
for...in gives you the keys:
const progress = { watched: 3, total: 6, streak: 2 };
for (const key in progress) {
console.log(key, progress[key]);
}
// watched 3
// total 6
// streak 2Or turn the keys into an array first, which lets you use the friendlier
for...of:
for (const key of Object.keys(progress)) {
console.log(key, progress[key]);
}Object.entries gives you key and value together, which is usually neatest:
for (const [key, value] of Object.entries(progress)) {
console.log(key, value);
}Avoid for...in on arrays. It works, but it hands you the indexes as strings
rather than numbers, which causes odd results the first time you try to add
them up.
Nested loops, and their cost
A loop inside a loop lets you pair every item with every other item — seating charts, grids, comparisons.
const sizes = ["S", "M"];
const colours = ["red", "blue"];
for (const size of sizes) {
for (const colour of colours) {
console.log(size, colour);
}
}
// S red, S blue, M red, M blueWatch the arithmetic. The inner loop runs completely for every single pass of the outer one, so the work multiplies rather than adds. Two lists of 10 is 100 steps, which is nothing. Two lists of 1,000 is a million steps, which is enough to freeze a browser tab. Nesting is not forbidden, but always ask how large those lists can get.
Try it yourself
Add a break inside the first loop so it stops after two lessons.
Where this is going
Loops are the foundation, not the destination. Once you are comfortable with
them, you will find that most loops over arrays are really one of a handful of
shapes — do something with each item, build a new list, keep the matching ones,
add everything up. Array methods like forEach, map and filter express
those shapes in a single line and say what you meant rather than how to walk
the list. That is the next lesson. Everything you learn here still applies
underneath.
What to remember
- A
forloop has three parts: start, condition checked before each pass, and step. - Use
i < array.length, never<=, or you read one place past the end. for...ofgives values and is the friendlier default for arrays.whilefits when you cannot know the number of passes in advance.breakends the loop;continueskips one pass.- Nested loops multiply the work — fine on small lists, risky on large ones.
Check yourself
4 questions · pass 3/4 to unlock Functions
1.What goes wrong in
for (let i = 0; i <= items.length; i++)?2.What is the difference between
breakandcontinue?3.In
for (const item of prices), what isitemon each pass?4.Two nested loops over the same list of 1,000 items do roughly how much work?
4 left to answer