Because they all close over the same variable i. Closures capture the variable, not the value. When the callbacks run, i is the final value, so all callbacks log it.
Closures Capture the Variable, Not the Value in JavaScript
Why do all setTimeout callbacks in a var loop log the same value in JavaScript?
The answer
More FAQs in Closures Capture the Variable, Not the Value in JavaScript
The variable. A closure holds a reference to the variable, not a snapshot of its value. If the variable changes before the callback runs, the closure sees the updated value. This is why var in a loop logs the final value.
Use let (creates a fresh binding per iteration), or an IIFE that passes the current value as a parameter (pass-by-value for primitives), or pass the value as an extra argument to setTimeout.
It captures a new parameter (j), which is a copy of the value (for primitives). The closure inside the IIFE closes over j, not the outer i. So even if i changes later, j holds the value at the time of the IIFE call.
Still have questions?
Browse all our FAQs or reach out to our support team
Want to upskill yourself?
Your learning library
Small steps. Big possibilities.
Find your next course. Build something great.