JavaScript Closure Inside Loops: A Common Pitfall Explained
One of the most misunderstood concepts in JavaScript—especially for beginners—is closure behavior inside loops. If you’ve ever used a for
loop and tried to run setTimeout
or another asynchronous function inside it, only to get unexpected results, you’re not alone.
In this article, we’ll break down why closures behave the way they do inside loops, the difference between var
and let
, and how to fix common issues developers encounter.
📌 What is a Closure in JavaScript?
A closure is created when a function retains access to variables from its outer scope, even after that outer function has finished executing. Here’s a quick example:
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
The function inner()
is a closure because it “remembers” the variable count
from its parent scope.
🔁 Closures in Loops: The Problem
Consider the following example using var
inside a for
loop:
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
Expected Output:
0
1
2
Actual Output:
3
3
3
Why?
Because var
is function-scoped, not block-scoped. All three closures inside the loop reference the same i
, which after the loop ends, is 3
.
✅ The Solution: Use let
(Block Scope)
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
Output:
0
1
2
Using let
creates a new scope for each iteration of the loop. Each setTimeout
closure captures its own copy of i
.
⚠️ Alternative Fix: IIFE (Immediately Invoked Function Expression)
Before let
was introduced, developers used an IIFE to capture the current loop value:
for (var i = 0; i < 3; i++) {
(function(j) {
setTimeout(() => {
console.log(j);
}, 1000);
})(i);
}
The IIFE creates a new function scope where j
takes the current value of i
, preserving it for the closure.
🧠 Best Practices
- ✅ Use
let
instead ofvar
inside loops. - ✅ Prefer readable, modern syntax over IIFEs unless you’re working in legacy environments.
- ✅ Understand closures thoroughly—they’re foundational to mastering JavaScript.
📚 Final Thoughts
Understanding how closures work inside JavaScript loops helps you avoid mysterious bugs and write more predictable, maintainable code. By using let
or wrapping logic in closures (IIFEs), you ensure each iteration of your loop behaves the way you expect.
Latest blog posts
Explore the world of programming and cybersecurity through our curated collection of blog posts. From cutting-edge coding trends to the latest cyber threats and defense strategies, we've got you covered.