Javascript does not have block scope. It has function scope. So, it behaves much differently than perl and other languages with block scope.
E.g., this simple perl program creates then invokes an array of closures:
my @closures;
for ( 1 .. 3 ) {
my $x = 1 / $_;
push @closures, sub { say $x };
}
$_->() for reverse @closures;It's output is:
0.333333333333333
0.5
1
A naive translation to javascript might be:
var closures = [];
for ( var n = 1; n <= 3; ++n ) {
var x = 1 / n;
closures.push(function () { console.log(x) });
}
closures.reverse().forEach(function (f) { f() });It's output is:
0.3333333333333333
0.3333333333333333
0.3333333333333333
To get the expected behavior, you need an additional function to create a new scope. And since variables declared anywhere within a function are accessible everywhere in the function, you might as well declare them at the top. In fact, that seems to be the preferred style.
var closures = [], n;
for ( n = 1; n <= 3; ++n ) {
closures.push(function (n) {
return function () { console.log(n) };
}(1 / n));
}
closures.reverse().forEach(function (f) { f() });It produces the intended output:
0.3333333333333333
0.5
1