第3回 JavaScriptのスコープと比べてみましょうか

さて、JavaScriptのスコープの話をしたいと思います。
あ、今回の内容は、3回目の記事にしてはレベルが高いと思いますので、JavaScriptにかなり精通しておられないなら、読み飛ばしたほうがいいかもしれません(あくまで、個人的レベル加減ですが)。



現状のおもなJavaScriptでは、
以下の記事のようになっています。(※ というか僕は最近知りました)

JavaScript のスコープに変数を動的に追加する - IT戦記
http://nanto.asablo.jp/blog/2006/07/08/437419



つまり、こんな感じです。

(function(){
 b=10;
 b++;
 var b;
 console.log(b); // 11
})();

結果:

11


つぎのように書いたのと同じになってしまうんですね。

(function(){
 var b;
 b=10;
 b++;
 console.log(b); // 11
})();

var b の位置が関数の頭にきました。このようにJavaScriptでは、変数宣言が書いたところではなく関数の頭に書いたこととみなされます。



Perlで同じイメージで書くと

use strict;

sub {
  $c=10;
  my $c;
  print "$c", "\n";
}->();

こんな感じになりますが、

これはもちろん、

Global symbol "$c" requires explicit package name at c line 4.
Execution of c aborted due to compilation errors.

エラーです。



ちゃんと次のように、

use strict;

sub {
  my $c=10;
  print "$c", "\n";
}->();

$cがはじめて出てきたところで、myをつけなければいけません。
結果:

10


よって、個人的には、JavaScriptだと変数を使いたいところで、変数を用意するのに抵抗があるのですが、Perlだと ミスがあってもuse stirctが教えてくれるので問題ありません。

今回の僕のJavaScriptの書き方は、JavaScript界隈ではよく見かける形だそうですが、

(function(){})() //この形

Perl

sub{}->() #この形

この書き方はあまりなじみがない方も多いかもしれません。今回はスコープの話をしたかったのでこの書き方の意味は申し訳ないですが、説明しません。ですから、今は気になさらないで結構です。(※ このあとじっくり、関数を学んび、リファレンスを学んだあとでやっと理解できる項目です)

でなぜ、JavaScript界隈で、

(function(){})() //この形

の書き方が流行ったのかというと、リンク先でも説明がなされているのですが、

{
 var a=1;
 var b=2;
}

console.log(a);

と書いても、

結果:

10

となってしまうわけです。

そこで、関数ならスコープの幅を決めれるので以下のように書けば、

(function(){
 var a=1;
 var b=2;
})();

console.log(a);


結果:

a is not defined

と教えてくれるわけです。


Perlだと、
「main関数はどこだ? プログラムはどこから処理されるのか」の記事で紹介しましたが、

use strict;

{
 my $c = 1;
 my $d = 2;
}

print "$c", "\n";

で、 { } がスコープを示すため、かのようにトリッキーなことをする必要はありません。



ということで、今回は、JavaScripと対比をしてみました。


それでは また〜