Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the scope of a Javascript variable declared in a for() loop?

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?

like image 892
Dylan Beattie Avatar asked Apr 28 '10 21:04

Dylan Beattie


People also ask

What is the scope of a variable in a for loop?

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.

What is the scope of the variable in JavaScript?

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.

Can we declare variable inside for loop in JavaScript?

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.

What does a for loop do in JavaScript?

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.


1 Answers

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)
);
like image 158
Quentin Avatar answered Sep 24 '22 02:09

Quentin