このスコープの「レキシカルさ加減」が、実は言語によって結構違うので、この機会にちょっとつっこんでおくことにする。
ハタさんのブログ : javascriptを初めて学ぶ人についてのおさらい。その1変数で宣言したものには、参照先が決まっています。その参照の範囲はスコープとも呼びます。
ここでいきなり問題。以下のコードは何をalertするでしょうか?
(function(){
var i = -1;
for(var i = 0; i < 10; i++){
/* whatever */
}
alert(i);
})()
これが-1でないのは、Perl Mongerにはびっくりです。
sub test{
my $i = -1;
for my $i (0..9){
}
warn $i
}
test();
% perl scope.pl -1 at scope.pl line 5.
ところが、pythonもrubyも、この点においてはむしろJavaScriptに近い挙動を示します。
def test():
i = -1
for i in range(0,10):
pass # do nothing
print i;
test()
% python scope.py 9
def test i = -1 (1..9).each do |i| end puts i end test
% ruby scope.rb 9
特にrubyのブロック引数がブロックローカルではない点は、オレオレ詐欺に引っかかったようなみじめさを感じさせずにいられません。
ちなみに、JavaScript 1.7では、let宣言が導入されたので、
(function(){
var i = -1;
for(let i = 0; i < 10; i++){
/* whatever */
}
alert(i);
})()
で-1とalert()するようになるとJohn Resigが一押ししてくれていたが、普及にどれくらいかかるのだろう。
Dan the Block Scope Advocate
http://nanto.asablo.jp/blog/2006/07/08/437419