無名関数を使ったブロックスコープ化の弱点

無名関数を使ったブロックスコープ化の弱点

JavaScriptではfor文の中やwhile文のなかだけで有効なブロックスコープは存在せず、varを使ってもスコープはその関数内全体で有効になる。これを防ぐ手段として無名関数を使う方法がある。しかしその方法にも弱点があった。クラス内で無名関数を定義した場合、thisが指すものが予期しないものになってしまう。


これだとvar iは関数全体からアクセスできる

for(var i = 0 ; i < array.length ; i++){
  array[i]に対する処理
}


これを防ぐ方法として(function{ … })();で囲む方法がある。

(function{
  for(var i = 0 ; i < array.length ; i++){
    array[i]に対する処理
  }
})();


しかしこの方法をクラス内で使う場合には危ない

this.name ="ジョー";
(function{
   this.name   //これは上で使ってるthis.nameとは別物
})();

こんな風にあるクラス内でこの無名関数を定義したとする。この場合この無名関数はグローバル関数として定義される。つまりこの関数が実行された場合、thisにはこのクラスではなく、グローバルスコープが指定される。

余談

これはクラス内でそのクラスに関しない関数を定義できてしまうことが原因である。イベントハンドラでthisキーワードを使った場合もこれと同様の事が起こる。*1

追記

withを使うとこういう問題は防げるらしい

*1:それについてはZDNetJavaScriptのthisキーワードをちゃんと理解するという記事を参考に。 http://builder.japan.zdnet.com/sp/javascript-kickstart-2007/story/0,3800083428,20371112-2,00.htm