Open1
久々に触れると忘れる、JavaScript特有の「巻き上げ(Hoisting)」備忘録
久しぶりにjsに触れるとjs特有の巻き上げ(Hoisting)を忘れることってありませんか?
1発で思い出せるように、それぞれの挙動と最小サンプルをまとめました。備忘録。
巻き上げ(Hoisting)とは?
Hoisting(巻き上げ)とは、スクリプトを実行する前に変数や関数の宣言部分がスコープの先頭に「持ち上げられる」仕組みのことです。
ただし、「持ち上げられる内容」や「使えるタイミング」は宣言の種類によって異なります。
巻き上げ対象の比較表
| 宣言の種類 | Hoistingされるか? | 巻き上げられる内容 | 宣言前の挙動 |
|---|---|---|---|
var |
される |
宣言のみ(初期値は undefined) |
undefined が返る |
let / const
|
されるが「一時的死域(TDZ)」に入る | 宣言されるが初期化前はアクセス不可 | ReferenceError |
function(関数宣言) |
される | 本体ごと | 呼び出し可能 |
const hello = function() {}(関数式) |
されるが初期化前はTDZ内 | 関数値は代入時に確定 | ReferenceError |
①var:宣言のみが巻き上げられる
console.log(a); // ✅ undefined(宣言だけ先に処理される)
var a = 10;
console.log(a); // 10
② let / const:巻き上げられるがTDZでブロック
try {
console.log(b); // ❌ ReferenceError(TDZ:一時的死域)
} catch (e) {
console.log("b before:", e.toString());
}
let b = 20;
console.log("b after:", b); // ✅ 20
try {
console.log(c); // ❌ ReferenceError(TDZ)
} catch (e) {
console.log("c before:", e.toString());
}
const c = 30;
console.log("c after:", c); // ✅ 30
③ 関数宣言:本体ごと巻き上げられる
hello(); // ✅ 呼び出し可能(本体が巻き上げられている)
function hello() {
console.log("こんにちは(関数宣言)");
}
④ 関数式:宣言前は呼び出せない
try {
hello2(); // ❌ ReferenceError
} catch (e) {
console.log("hello2 before:", e.toString());
}
const hello2 = function() {
console.log("こんにちは(関数式)");
};
hello2(); // ✅ 実行可能
まとめ
- 巻き上げ(hoisting)はjs特有、たまに触れると忘れるのでサクッと確認できるといいよね^ ^
- そもそも'var'なんぞ使うなってことだよね^ ^
- let / const は巻き上げ「されない」ではなく「されるけど使えない」