Check out the following snippet of HTML/Javascript code:
<html>
<head>
<script type="text/javascript">
var alerts = [];
for(var i = 0; i < 3; i++) {
alerts.push(function() { document.write(i + ', '); });
}
for (var j = 0; j < 3; j++) {
(alerts[j])();
}
for (var i = 0; i < 3; i++) {
(alerts[i])();
}
</script>
</head><body></body></html>
This outputs:
3, 3, 3, 0, 1, 2
which isn't what I was expecting - I was expecting the output 0, 1, 2, 0, 1, 2,
I (incorrectly) assumed that the anonymous function being pushed into the array would behave as a closure, capturing the value of i
that's assigned when the function is created - but it actually appears that i
is behaving as a global variable.
Can anyone explain what's happening to the scope of i
in this code example, and why the anonymous function isn't capturing its value?
In C/C++, the scope of a variable declared in a for or while loop (or any other bracketed block, for that matter) is from the open bracket to the close bracket.
The scope of a variable is the region of your program in which it is defined. JavaScript variables have only two scopes. Global Variables − A global variable has global scope which means it can be defined anywhere in your JavaScript code.
If a variable is declared inside a loop, JavaScript will allocate fresh memory for it in each iteration, even if older allocations will still consume memory.
A for loop repeats until a specified condition evaluates to false. The JavaScript for loop is similar to the Java and C for loop. When a for loop executes, the following occurs: The initializing expression initialExpression , if any, is executed.
The scope is the function that the variable is defined in (except there isn't one, so it is global).
The anonymous function you are passing is accessing the variable defined in the parent function's (again global) scope.
You need an actual closure.
alerts.push(
function (foo) {
return function() {
document.write(foo + ', ');
}
}(i)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With