ホイスティングとは?
コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること。
このホイスティングのことを宣言の巻き上げとも表現する。
それでは一つ関数を宣言してみる。
a();
function a() {
console.log("a is called");
}
関数の実行a();を関数の実効より前で呼んでみる。
このようにしても
a is called
と、console.logに表示される。
関数や変数の宣言はコードの実行前にすでに宣言の定義がメモリー上に存在するため。
var 宣言の場合
console.log(b); //宣言を上に持ってきた場合
var b = 0;
undefined
と、console.logに表示される。
変数のvarの場合まだ変数は宣言されてないのでundefinedになる。
変数bのメモリスペースを確保した状態でundefinedという特殊は値を設定する。
undefinedはジャバスクリプトエンジン上で自動的に設定される値。
varなどの宣言を見つけたらメモリスペースを確保してundefinedを設定している。
let const 宣言の場合
console.log(b);
let b = 0;
//constでも同じ
undefinedではなくエラー表示がでる。
Uncaught ReferenceError
Uncaught ReferenceError は変数が初期化されていないという意味。
let constの場合はundefinedの初期化設定はされない。
このためvarとの挙動の違いでvarは非推奨になっている。
※変数宣言は let, const を使うようにすること。
無名関数を 代入する関数の定義の方法もある。これを関数式という。
このようは関数式の場合変数のホイスティングと同じになるのでこの場合エラーになる。
関数宣言と関数式の違いに注意
a();
function a() {
console.log(c); //Uncaught ReferenceErrorエラーになる。
let c = 1;
d();
function d() {
console.log("d is called");
}
console.log("a is called");
}
console.log(b);
let b = 0;
変数は宣言より前で呼ぶとエラーになる。
関数は宣言文より前に実行してもエラーにはならない。
このようにコンテキストが生成されるごとにホイスティングが発生し、宣言部がメモリスペースに展開される。
関数式で記述した場合
a();
const a = function () { //無名関数を 代入する関数の定義の方法もある。これを関数式という。
console.log(c);
var c = 1;
d();
function d() {
console.log("d is called");
}
console.log("a is called");
};
console.log(b);
let b = 0;
無名関数を 代入する関数の定義の方法もある。これを関数式という。
このようは関数式の場合変数のホイスティングと挙動が同じになるので宣言部より上で呼ぶと、この場合エラーになる。
関数宣言と関数式の違いに注意