I had this idea that, as soon as you made a closure, all the variables were neatly packaged up and were immutable outside of the closure itself. Then I saw some weird behaviour in Javascript, and investigated further.
Turns out that my assumption was just plain wrong. For instance:
test.pl: ---------------------------------------------- sub say_hello { my $name = shift; my $text = 'Hello '.$name; my $sayAlert = sub { print "$text\n" }; $text = "Not in Perl you don't"; $sayAlert->(); } say_hello('Bob'); ---------------------------------------------- > perl test.pl Not in Perl you don't
test.pl: ---------------------------------------------- sub say_hello { my $name = shift; my $sayAlert; { my $text = 'Hello '.$name; $sayAlert = sub { print "$text\n" }; } my $text = "Not in Perl you don't"; $sayAlert->(); } say_hello('Bob'); ---------------------------------------------- > perl test.pl Hello Bob
However, try the same thing in Javascript, and it doesn't work:
function sayHello(name) { var sayAlert; { var text = 'Hello ' + name; sayAlert = function() { alert(text); } } var text='How confused am I?'; sayAlert(); } sayHello('Bob'); ---> "How confused am I?"
It turns out that, unlike Perl, creating a new (nested) block in JS does NOT create a new scope. Instead a new scope is created when a function is declared. Oh, and it doesn't give you any "variable text redefined" warnings either.
|
|---|