JavaScript Curriculum
Do It Again (and Again)
mediumNexus has 2,400 user accounts. Your task: find every account that hasn't logged in for 90 days and mark it inactive. You could write 2,400 if statements. Or you could write one loop that does the same check for every single account — and handles 240,000 just as easily.
The problem with doing things once
A function runs when you call it. That's one execution. But most real problems require the same logic applied to every item in a collection — every user, every product, every row in a table.
Loops are the mechanism that repeats a block of code as many times as needed, controlled by a condition you define. They're one of the most fundamental building blocks in all of programming.
The for loop — the classic, explicit choice
The for loop packs everything into one line: where to start, when to stop, how to advance.
Three parts, separated by semicolons inside the parentheses:
| Part | Example | Job |
|---|---|---|
| init | let i = 0 | Runs once before the first iteration — sets up the counter |
| condition | i < 5 | Checked before every iteration — if false, the loop stops |
| update | i++ | Runs after every iteration body — advances the counter |
Step through the loop below. Watch each part light up in sequence — and notice exactly when the condition check causes the loop to end:
output
nothing logged yet…
Four loop types — same problem, different tools
JavaScript gives you four ways to loop. The right choice depends on what you're iterating over and what information you need inside the loop.
use when
You know exactly how many times to loop, or need the index.
anatomy
init ; condition ; update — all three in one place. Most explicit.
The practical decision tree:
- Iterating an array and need the value? →
for...of - Iterating an array and need the index? →
forwith counter - Iterating an object's keys? →
for...in - Looping until a condition changes (not a fixed collection)? →
while
The while loop — condition-driven repetition
while keeps looping as long as its condition is true. There's no built-in counter — you manage state yourself:
A classic while use-case — keep trying until it works:
This is impossible to express cleanly as a for loop because you don't know how many iterations you'll need.
for...of — the clean modern choice for arrays
When you want every value from an array and don't care about the index, for...of is the most readable option:
No counter, no products[i], no index arithmetic. The variable product is a new const binding for each iteration — safe, clear, and impossible to accidentally mutate.
for...of works on any iterable: arrays, strings, Set, Map, and more.
for...in — iterating object keys
for...in gives you the keys of an object, one by one:
Note that user[key] uses bracket notation — key is a variable containing the property name, so dot notation won't work.
break and continue — steering the loop
Two keywords give you fine-grained control over loop execution. Step through the demo to see the difference:
console output
nothing logged yet…
break = emergency exit — terminates the entire loop immediately.
continue = skip and move on — jumps to the next iteration without running the rest of the body.
Building the inactive-user scanner
Here's the pattern your challenge asks you to build:
for...of is the right choice here: you want every value, you don't need the index, and you're filtering by a condition on each item's properties.
Both work. The for...of version removes all the index plumbing that has nothing to do with the actual logic.
Challenge
Given an array of user objects, each with a name and daysSinceLogin, write a function called findInactiveUsers(users) that returns a new array containing only the users whose daysSinceLogin is greater than 90. Use a for...of loop — don't use .filter(). Log each inactive user's name and daysSinceLogin.
Do It Again (and Again)
mediumNexus has 2,400 user accounts. Your task: find every account that hasn't logged in for 90 days and mark it inactive. You could write 2,400 if statements. Or you could write one loop that does the same check for every single account — and handles 240,000 just as easily.
The problem with doing things once
A function runs when you call it. That's one execution. But most real problems require the same logic applied to every item in a collection — every user, every product, every row in a table.
Loops are the mechanism that repeats a block of code as many times as needed, controlled by a condition you define. They're one of the most fundamental building blocks in all of programming.
The for loop — the classic, explicit choice
The for loop packs everything into one line: where to start, when to stop, how to advance.
Three parts, separated by semicolons inside the parentheses:
| Part | Example | Job |
|---|---|---|
| init | let i = 0 | Runs once before the first iteration — sets up the counter |
| condition | i < 5 | Checked before every iteration — if false, the loop stops |
| update | i++ | Runs after every iteration body — advances the counter |
Step through the loop below. Watch each part light up in sequence — and notice exactly when the condition check causes the loop to end:
output
nothing logged yet…
Four loop types — same problem, different tools
JavaScript gives you four ways to loop. The right choice depends on what you're iterating over and what information you need inside the loop.
use when
You know exactly how many times to loop, or need the index.
anatomy
init ; condition ; update — all three in one place. Most explicit.
The practical decision tree:
- Iterating an array and need the value? →
for...of - Iterating an array and need the index? →
forwith counter - Iterating an object's keys? →
for...in - Looping until a condition changes (not a fixed collection)? →
while
The while loop — condition-driven repetition
while keeps looping as long as its condition is true. There's no built-in counter — you manage state yourself:
A classic while use-case — keep trying until it works:
This is impossible to express cleanly as a for loop because you don't know how many iterations you'll need.
for...of — the clean modern choice for arrays
When you want every value from an array and don't care about the index, for...of is the most readable option:
No counter, no products[i], no index arithmetic. The variable product is a new const binding for each iteration — safe, clear, and impossible to accidentally mutate.
for...of works on any iterable: arrays, strings, Set, Map, and more.
for...in — iterating object keys
for...in gives you the keys of an object, one by one:
Note that user[key] uses bracket notation — key is a variable containing the property name, so dot notation won't work.
break and continue — steering the loop
Two keywords give you fine-grained control over loop execution. Step through the demo to see the difference:
console output
nothing logged yet…
break = emergency exit — terminates the entire loop immediately.
continue = skip and move on — jumps to the next iteration without running the rest of the body.
Building the inactive-user scanner
Here's the pattern your challenge asks you to build:
for...of is the right choice here: you want every value, you don't need the index, and you're filtering by a condition on each item's properties.
Both work. The for...of version removes all the index plumbing that has nothing to do with the actual logic.
Challenge
Given an array of user objects, each with a name and daysSinceLogin, write a function called findInactiveUsers(users) that returns a new array containing only the users whose daysSinceLogin is greater than 90. Use a for...of loop — don't use .filter(). Log each inactive user's name and daysSinceLogin.