JavaScript: 変数宣言の巻き上げ(ホイスティング)
JavaScript特有の、変数宣言の巻上げ(ホイスティング)について説明します。
わかりやすいように具体例で順を追って見ていきます。
まず、次のような1行だけのコードがあるとします。 宣言も何もされていない変数内容を出力しようとした場合、 これを実行するとどうなるでしょうか?
console.log(a);
実行結果は、「エラー」となります。 Firefoxでのエラーメッセージは、「ReferenceError: a is not defined」となります。
次に、変数宣言だけを行った変数内容を出力した場合はどうなるでしょうか? (変数の宣言だけで初期化は行っていません)
var a;
console.log(a);
実行結果は「undefined」となります。 このように、宣言はされているけれど、 値が代入されていない変数の値は「undefined」になることを覚えておいてください。
次は、宣言も初期化も行われている変数内容を出力した場合です。
var a = 5;
console.log(a);
実行結果はもちろん「5」です。
ここまでが準備編です。これからが変数宣言の巻上げについての説明となります。
変数宣言の巻上げの具体例
では、次のようなコードを実行するとどうなるでしょうか? 事前に変数宣言がされておらず、console.log()の後に変数が宣言されている場合です。
console.log(a);
var a;
実行結果は「undefined」となります。
JavaScript以外の他の言語ならエラーとなる所ですが、 JavaScriptの場合は、先頭で変数宣言されていると見なされて エラーとはならずに、「undefined」となります。
これが「変数宣言の巻上げ(ホイスティング)」と呼ばれるものです。 変数宣言部分が巻き上げられて、実際は下のコードのように解釈されています。 ですから実行結果が「undefined」となります。
var a;
console.log(a);
次に、下のコードを実行するとどうなるでしょうか? 先ほどはconsole.log()の後に変数宣言のみでしたが、 今回は初期化もされています。
console.log(a);
var a = 5;
実行結果は「undefined」となります。
「5」が出力されるのでは?と予想した人がいるかもしれませんが、 あくまで宣言が巻き上げられるだけで、代入部分は巻き上げられません。 ですから実行結果が「undefined」となります。
「変数の巻上げ」ではなく、「変数宣言の巻上げ」なので注意してください。
他のプログラミング言語経験者からみると、 この「変数宣言の巻上げ」は違和感があると思います。 JavaScript特有の仕様なので、 変数宣言はなるべく最初に行った方が良いでしょう。