The IIFE creates a new function scope per iteration and passes i as a parameter (j). Primitives are passed by value, so j is a copy of i at that iteration. The closure captures j, not i.
Fixing the setTimeout Closure Bug Three Ways in JavaScript
How does the IIFE fix the setTimeout closure bug in JavaScript?
The answer
More FAQs in Fixing the setTimeout Closure Bug Three Ways in JavaScript
Use let (fresh binding per iteration), use an IIFE (new function scope with pass-by-value parameter), or use setTimeout's extra arguments (pass the current value as an argument to the callback).
let. It is the cleanest and most readable. It creates a fresh binding per iteration without extra nesting or arguments. Use it in all ES6+ code.
setTimeout(fn, delay, ...args) passes the extra arguments to the callback. Each call captures the current value of i as an argument. The callback receives j (a copy), not the shared i.
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.