=== 発展的な知識 ===
==== <code>var</code>の巻き上げ ====
『[[JavaScript/関数]]』で説明する。
<code>var</code>で宣言された変数を関数内で使う場合に、値の代入は代入した場所で行われるが、宣言(および宣言に伴う代入)は関数内のどこでしても関数の先頭でしたことになるという落とし穴が存在します。この挙動は<code>var</code>の巻き上げ(<code>var</code> hoisting)と呼ばれます。
<syntaxhighlight lang="JavaScript">
(function() {
console.log(dream); // undefined -- なぜかReferenceErrorにならない
var dream = true;
document.write(dream); // true
})();
</syntaxhighlight>
上記コードでは表示結果として、trueが表示されます。
なお、上記コードの関数は、無名関数と言われる種類の関数です。(無名関数について詳しくは『[[JavaScript/関数]]』で説明する。)
let では、巻き上げは発生しないです。キーワード無しでも巻き上げは発生しないです。
関数内でvarで宣言した場合にだけ、巻き上げが発生します。
巻き上げが起きるのは、あくまで関数内での出来事であるので、関数を用いてない場所では、巻き上げは行われません。
==== その他 ====
{{コラム|console画面の開き方と使い方|
:1. webブラウザを開く。
}}
なぜ宣言する前に<code>dream</code>を参照している(ように見える)のにエラーにならないかというと、これは次のように解釈されるからです。
<syntaxhighlight lang="JavaScript">
(function() {
var dream; // <--- 暗黙的な宣言の移動
console.log(dream); // undefined
dream = true;
console.log(dream); // true
})();
</syntaxhighlight>
これに巻き込まれないよう、宣言する前に変数を使わないように注意しましょう。
<code>var</code>にはこういった問題があるのですが、かといって「常に関数の先頭で全部の変数を宣言するようにし、途中で<code>var</code>を使わないようにする」というのでは、昔の[[C言語|C]]みたいで、あまりに退屈です。ハッカーは問題を解くのに適した言語を''作る''べきで、言語に人間が合わせるべきではありません。そもそもの問題は<code>var</code>がブロックスコープをもたないことにあるのだから、ブロックスコープをもつ<code>var</code>を発明するのが筋です。
※ 検索用アンカー {{anchor|let}}
|