宣言の巻き上げ処理(ホイスティング)

(文と宣言)
https://wp-p.info/tpl_rep.php?cat=js-intermediate&fl=r9

下記の場合は変数『x』の宣言の前に『x』を出力する、という形になっているためエラーが予測されるが、JavaScriptではエラーにならない。ちゃんと『undefined』と出力してくれる。

function hoge(){
    console.log(x);
    var x;
}
hoge();

なぜかというと、JavaScriptでは『常に宣言はスコープの先頭で行われたことにする』という処理を裏側で行っている。JavaScriptでのスコープは関数の中以外では存在しないため、つまり『常に宣言は関数の中の先頭で行われたことにされる』ということになる。これが『ホイスティング』と呼ばれる現象である。

function hoge(){
    console.log(x); // 巻き上げられるのは宣言のみなので『undefined』と出力される
    var x = 0; // ここで代入処理が行われる
    console.log(x); // 代入処理が行われた後なので『0』が出力される
}
hoge();

以下は関数『hoge』の最初にグローバル変数『x』の値を出力するつもりでミスをしてしまった例である。

var x = 0; // ここはグローバル変数
function hoge(){
    console.log(x);
    // ここに処理が沢山書いてあるとする
    var x = 1;
}
hoge();

上記のサンプルでコンソールに出力されるのは『0』ではなく『undefined』である。
なぜかというと宣言のみが巻き上げられてしまうため、以下のソースコードと同等になるからである。

var x = 0; // ここはグローバル変数
function hoge(){
    var x; // 宣言のみが巻き上げられる。グローバル変数ではなくローカル変数『x』の定義となるので『undefined』が入る
    console.log(x); // ローカル変数『x』の『undefined』が出力される
    // ここに処理が沢山書いてあるとする
    x = 1; // ローカル変数『x』に『1』が代入される
}
hoge();

このように意図せずグローバル変数と同じ名前でローカル変数を定義してしまった際になぜかグローバル変数が取得できない、という展開になってしまう。
なお、巻き上げ処理は変数だけでなく配列やオブジェクトなどでも起こる。

inserted by FC2 system