Problem Statement
You're given the following JavaScript function that is supposed to print numbers 1 to 5, each with a 1-second delay. But something is wrong!
javascript
Copy
Edit
function printNumbers() {
for (var i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
}
printNumbers();
Expected Output:
Copy
Edit
1
2
3
4
5
Actual Bugged Output:
Copy
Edit
6
6
6
6
6
π Whatβs the Bug?
The issue is caused by closures and the var keyword.
setTimeout stores a reference to i, but by the time the callback executes, the loop has already finished and i = 6.
Hence, all iterations log 6 instead of 1, 2, 3, 4, 5.
β
How to Fix It?
Solution 1: Use let instead of var (Block Scope Fix)
javascript
Copy
Edit
function printNumbers() {
for (let i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
}
printNumbers();
πΉ let creates a block-scoped variable for each loop iteration, fixing the issue.
Solution 2: Use an IIFE (Immediately Invoked Function Expression)
javascript
Copy
Edit
function printNumbers() {
for (var i = 1; i <= 5; i++) {
(function(num) {
setTimeout(function() {
console.log(num);
}, num * 1000);
})(i);
}
}
printNumbers();
πΉ The IIFE captures i as num, preserving the correct value for each iteration.
β‘ Final Thoughts
Understanding closures and scope is crucial for mastering JavaScript! Which solution do you prefer? Let me know in the comments! π¬π₯
Top comments (0)