2011年3月24日木曜日

javascriptでの関数内関数について

javascriptでの関数内関数について、基礎的な事が良くわかってなかったのでメモしておきます。
ruby on railsのalias_method_chain的な動きをさせたくて

function foo() {
  console.debug("foo");
}

var fooWithoutBar = foo;

foo = function() {
  console.debug("before foo");
  fooWithoutBar();
  console.debug("after foo");
}

foo();

と書きましたが、これは問題なく動きます。ところが

(function() {
  function foo() {
    console.debug("foo");
  }

  var fooWithoutBar = foo;

  foo = function() {
    console.debug("before foo");
    fooWithoutBar();
    console.debug("after foo");
  }
}());

foo(); // error

は動きません。関数内関数は、本当に関数内関数として動きます!rubyとは違いますな。。

8行目の代入がグローバルスコープ?とか考えてしまいましたが
・変数fooはローカルスコープで宣言されている(2行目)
・8行目で変数を探す際、ローカルスコープから探し始める
・ローカルスコープで発見!
・その変数に新しい関数オブジェクトを代入
という訳で、上記の即時関数の外ではfooは見えません。

ちなみに

  var fooWithoutBar = foo;
  ↓
  fooWithoutBar = foo;

とすると、即時関数外でもfooWithoutBar()は呼び出せます。代入時点ではfooWithoutBarという変数は存在しないのでグローバルスコープの変数となる為と思われます。

0 件のコメント:

コメントを投稿