Skip to content

Instantly share code, notes, and snippets.

@semifor
Last active December 16, 2015 08:39
Show Gist options
  • Select an option

  • Save semifor/5407526 to your computer and use it in GitHub Desktop.

Select an option

Save semifor/5407526 to your computer and use it in GitHub Desktop.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment