JavaScript ES2024 ·
✓ verified by execution on 2026-08-10
If you want to run the same code multiple times, you could use a while loop, but you would have to carefully manage a counting variable yourself. You have to remember to set it up before the loop, check it in the condition, and manually change it inside the loop body. If you forget to update the variable, your program will freeze forever in an infinite loop.
To solve this problem, JavaScript provides the for statement. It creates a loop by packing the setup, the condition, and the update step all into one neat package at the top of the loop.
Anatomy of a for Loop
Here is the most common way you will see a for loop written:
javascript
for (let i = 0; i < 3; i++) { console.log(i);}
Output
0
1
2
Your output
Notice that the parentheses contain three separate expressions separated by semicolons. Let’s look at the exact order in which JavaScript evaluates them:
Execution flow of a for loop
Initialization: This runs exactly once, before the loop even starts. It is usually where you declare your counting variable (like let i = 0).
Condition: This is evaluated before every single iteration. If it is true, the loop body runs. If it is false, the loop immediately stops.
Afterthought: This is executed at the very end of every iteration, right after the body finishes, but before the next condition check. It is typically used to increment or decrement the counter.
We can prove that the initialization runs exactly once by tracking an outside variable.
javascript
let count = 0;for (let i = (count += 5); i < 10; i++) { console.log(i);}console.log('Final count:', count);
Output
5
6
7
8
9
Final count: 5
Your output
If the initialization ran multiple times, count would have kept increasing. It stayed at 5 because that piece of the statement only executes once.
Skipping the Expressions
Three slots separated by semicolons look like three required parts. All three are optional.
If you omit the condition, JavaScript simply defaults it to true. This means you can leave slots blank if you are managing the logic elsewhere, or even omit them all to create an infinite loop.
javascript
let i = 0;for (; i < 3;) { console.log(i); i++;}
Output
0
1
2
Your output
Going Backwards and By Steps
You are not restricted to just counting up by 1. The afterthought expression can be absolutely anything. If you want to count downwards, or skip numbers, you simply change the condition and the afterthought.
Predict the outputjavascript
Read the code. What exactly will it print? Commit to an answer before you look.
for (let i = 5; i > 0; i -= 2) { console.log(i);}
Output
5
3
1
You predicted
The Scope Trap: let vs var
When you declare a variable using let inside the initialization block, JavaScript does something very clever: it creates a brand new lexical scope for each iteration of the loop. This means the variable i inside the loop body is actually a fresh binding every time.
javascript
for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0);}
Output
0
1
2
Your output
However, if you use the older var keyword, the variable is shared across all iterations. By the time the asynchronous setTimeout functions actually run, the loop has already finished and the shared var has reached its final value.
javascript
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0);}
Output
3
3
3
Your output
This is one of the many reasons why you should always use let in modern JavaScript!
Check yourself
If you declare a loop variable using the "var" keyword inside the for loop initialization, what happens?
Reveal answer
The variable is shared across iterations and leaks into the outer scope. — When declaring variables with let in the initialization, a new lexical scope is created for each iteration. Using var shares the binding and leaks it outside the loop.
Must a for loop always contain the initialization, condition, and afterthought?
Reveal answer
No, all three expressions are entirely optional. — All three expressions (initialization, condition, afterthought) are optional in a for loop. If you omit the condition, it defaults to true.
Exactly when does the afterthought expression execute in a for loop?
Reveal answer
Right after the loop body finishes, before the next condition check. — The afterthought is the final step of an iteration, executing just before control returns to the condition check for the next loop.
Does a for loop always have to count up by 1?
Reveal answer
No, the afterthought can be any expression, like i -= 2. — The afterthought can be any expression, such as decrementing (i--), modifying by other amounts (i += 5), or even completely unrelated logic.
Challenges
Challenge 1 +20 XP
Write a `for` loop that logs all even numbers from 2 up to 10 (inclusive).
javascript
Test 1 — expects "2\n4\n6\n8\n10"
Need a hint? (−25% XP)
Start your initialization at 2, set your condition to `i <= 10`, and your afterthought to `i += 2`.
Show solution (0 XP)
for (let i = 2; i <= 10; i += 2) { console.log(i);}
Challenge 2 +20 XP
Write a `for` loop that counts backwards from 5 down to 1 (inclusive) and logs each number.
javascript
Test 1 — expects "5\n4\n3\n2\n1"
Need a hint? (−25% XP)
Initialize your variable at 5. Your condition should keep the loop running as long as it's greater than 0, and the afterthought should decrement (`--`).