JavaScriptにおける変数のスコープ
JavaScriptのスコープはCやC++と少し違う.
変数のスコープ
次のようなプログラムを考えてみる.
var a; b = 'b:global'; function f() { a = 'a':global; var c = 'c:local'; d = 'd:global'; } f(); document.write(a); // a:globalが出力される document.write(b); // b:globalが出力される document.write(c); // undefinedが出力される document.write(d); // d:globalが出力される
関数外で宣言したvar aは,グローバル変数と見なされる.そのため,f()関数内でa = 'a:global'とすると,グローバル変数aの中身がa:globalに変更される.
b = 'b:global'はvar b = 'b:global'と等価である.varを用いなくとも,変数は暗黙的に宣言される.
関数内でvar c;と変数を宣言した場合,その変数は関数内のみで有効なローカル変数となる.そのため,関数外でdocument.write(c);とするとundefinedが出力される.
関数内でvarを使わずに変数を用いた場合,その変数は暗黙的にグローバル変数として宣言される.
すなわち,
function f() { foo = 0; }
は,
var foo; function f() { foo = 0; }
と同じである.
ローカル変数のスコープ
次に,次のようなプログラムを考えてみる.
var foo = 'global'; function f() { document.write(foo); // undefinedが出力される var foo = 'local'; document.write(foo); // localが出力される } document.write(foo); // globalが出力される
関数内で定義したvar fooはグローバル変数のfooを隠す.また,JavaScriptでは,ローカル変数のスコープは関数全体であるため,f()関数内でのdocument.write(foo)はundefinedを出力する.
このプログラムは次と等価である.
var foo = 'global'; function f() { var bar; document.write(bar); bar = 'local'; document.write(bar); } document.write(foo);
ブロックと変数のスコープ
C言語の場合,ローカル変数のスコープはブロック単位である.
void func() { int foo = 0; { int bar = 1; printf("%d\n", foo); // 0が出力される printf("%d\n", bar); // 1が出力される } printf("%d\n", foo); // 0が出力される printf("%d\n", bar); // エラー.barは未定義の変数 }
JavaScriptの場合,ローカル変数のスコープはブロック単位ではなく関数単位であるので注意が必要である.
function f() { var foo = 0; { var bar = 1; doument.write(foo); // 0が出力される doument.write(bar); // 1が出力される } doument.write(foo); // 0が出力される doument.write(bar); // 1が出力される }