>>2var Global = 1;
function Outer () {
var localOuter = 2;
function Inner () {
var localinner = 3;
Global; // ???
}
}
今、関数 Inner 内で変数 Global を参照したとします。エンジンはまず、関数 Inner 内を探しますが見つかりません。次に、親文脈である関数 Outer 内を探しますが、ここでも見つかりません。さらにその親文脈であるグローバル文脈を探すと、ついに Global が見つかります。
ここで、もし関数 Inner 内で var Global 宣言したらどうなるでしょうか。関数 Inner 内に変数 Global の宣言が見つかりますので、ここで探索終了となります。このとき、グローバル文脈の変数 Global には何も影響がありません。
var Global = 1;
function Outer () {
function Inner () {
var Global = 4;
Global; // 4
}
Inner ();
}
Outer ();
Global; // 1
このように、文脈をさかのぼって変数を探す仕組みをスコープチェーンと呼びます。var 宣言というのは、スコープチェーンに変数を追加する仕組みです。
さて、関数 Inner 内で var 宣言せずに変数 Global2 を初期化してしまうと、スコープチェーンを次々にさかのぼって Global2 を探しますが、見つかりません。仕方がないので、スコープチェーンの最後尾であるグローバル文脈に、変数 Global2 を作成して初期化します。
function Outer () {
function Inner () {
Global2 = 4;
}
Inner ();
}
Global2; // Error: not defined
Outer ();
Global2; // 4
ですから、var 宣言せずに初期化した変数はグローバル変数になります。
もっとも、グローバルな文脈で var 宣言した変数も、やはりグローバル変数です。グローバル変数であろうとなかろうと、変数は var 宣言してスコープを明示すべきです。
蛇足ながら、グローバル変数はグローバルオブジェクトのプロパティです。ブラウザ上では、グローバルオブジェクトは window に相当しますので、グローバル変数 Global は window.Global と等価です。
ローカル変数は、関数実行時に作成される不可視のオブジェクト Activation のプロパティとなります。