Wednesday, February 19, 2025

JavaScript, JavaScript Scoping Issue, CYD

JavaScript Scoping Issue
In JavaScript,
const array = [1, 2, 3, 4];
for (var i = 0; i < array.length; i++) {
setTimeout(function () {
console.log("I am at index " + i);
}, 3000);
}
We get the following:
I am at index 4
I am at index 4
I am at index 4
I am at index 4
Why?
Answer: The code behaves this way due to how closures and variable scoping work in JavaScript, particularly with the 'var' keyword.
When you declare a variable using 'var' within a loop, 'var' has function scope, not block scope. This means that the variable 'i' is shared across all iterations of the loop and is not unique to each iteration. By the time the 'setTimeout' callback executes, the loop has already completed, and the value of 'i' is the last value it was assigned, which is 4.
Thus, each of the 'setTimeout' callbacks logs the final value of 'i', which is 4.
To fix this issue and ensure that each 'setTimeout' callback has the correct value of 'i', you can use an IIFE (Immediately Invoked Function Expression) or the 'let' keyword (which has block scope) to create a new scope for each iteration.
const array = [1, 2, 3, 4];
for (var i = 0; i < array.length; i++) {
(function (index) {
setTimeout(function () {
console.log("I am at index " + index);
}, 3000);
})(i);
}

const array = [1, 2, 3, 4];
for (let i = 0; i < array.length; i++) {
setTimeout(function () {
console.log("I am at index " + i);
}, 3000);
}

In the first solution, the IIFE creates a new scope for each iteration and captures the current value of 'i' as 'index'. In the second solution, the 'let' keyword ensures that 'i' has block scope, so each iteration gets a unique 'i'.

No comments:

Post a Comment

Hot Topics