Kinopyo's Blog

I love this game.

Javascript変数にブロックスコープはない

2010年02月12日 by kinopyo | JavaScript



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の先頭に置くのが大事ですね。



Tags:

You can leave a response, or trackback from your own site.

関連記事

Leave a Reply

Get Adobe Flash playerPlugin by wpburn.com wordpress themes