JavaをやってからJavascriptを触ったので、
Javascript変数にブロックレベルのスコープがないことにビックリしました。
if文ブロックか、forループブロックか関係なく、
function内に定義された変数は全て同じスコープ:functionのスコープになります。
例えば
function test(o) {
var i = 0; // i is defined throughout function
if (typeof o == "object") {
var j = 0; // j is defined everywhere, not just block
for(var k=0; k < 10; k++) { // k is defined everywhere, not just loop
document.write(k);
}
document.write(k); // k is still defined: prints 10
}
document.write(j); // j is defined, but may not be initialized
}
変数kとjはそれぞれif文のブロック、forループのブロック内に定義されたが、
実はfunctionのスコープとなりfunction内ならどこでも参照できます。
これをしっかり理解しないと以下のようなミスが起こしやすいです。
var scope = "global";
function test() {
alert(scope); // Displays "undefined", not "global"
var scope = "local"; // Variable initialized here, but defined everywhere
alert(scope); // Displays "local"
}
test();
一番目のalertは"global"だと思ったらこの記事を読む価値はあるでしょう。
一番目のalertは"undefined"を表示します。
なぜならさっき言ったように変数のスコープはfunction内に跨るのです。
varで宣言する位置、順番と関係ありません。
ここではfunction内で同じ名前でscopeという変数が宣言され、
"global"の値を持つグローバル変数は上書きされました。
そして一番目のalert時のscopeは初期化されていないため、undefinedとなってしまいます。
上記のコードを書き換えると以下と同じです。
function test() {
var scope; // Local variable is declared at the start of the function
alert(scope); // It exists here, but still has "undefined" value
scope = "local"; // Now we initialize it and give it a value
alert(scope); // And here it has a value
}
誤解を招かないように変数の宣言はfunctionの先頭に置くのが大事ですね。