オライリーのJavaScriptの本読んでてスコープのところでつまった。


var scope = "global";
function f() {
  alert(scope);
  var scope = "local";
  alert(scope);
}
f();

これをfirebugで実行すると1回目のalertで「undefined」2回目のalertで「local」が表示される。

でも、関数内でvar scopeをコメントアウトすると


var scope = "global";
function f() {
  alert(scope);
  //var scope = "local";
  alert(scope);
}
f();

2回とも「global」が表示される。

なんで?
最初のコードの変数scopeは関数外で宣言されてるからundefinedなのはわかるけど、後のコードは関数外のグローバル変数見に行ってもいいの?

----------------------------------------------------------------------------------------------------------------------------------
※追記
----------------------------------------------------------------------------------------------------------------------------------
コメントとかチャットで色々教えてもらって、たぶんわかった。


var scope = "global";
function f() {
  alert(scope);
  var scope = "local";
  alert(scope);
}
f();

こう書いても実行時の解釈は


var scope = "global";
function f() {
  var scope; // 関数内スコープ変数scopeが定義される
  alert(scope); // 関数内スコープ変数が参照されるため、もちろん未定義値(undefined)が返される
  scope = "local"; // 関数内スコープ変数scopeに"local"をセット
  alert(scope); // local
}
f();

ってなるらしい。

f()を呼び出すときに初めて「function f()〜〜」の上から順番に読み込むんだと思ってたけど、違うみたい。
f()を呼ぶときにはもうf関数は定義済み。

関数内に目的の変数名のローカル変数が無いと同じ名前のグローバル変数探しに行く。
ってことでいいのかな。

よくわかりました。