Open1

久々に触れると忘れる、JavaScript特有の「巻き上げ(Hoisting)」備忘録

tech_mwtech_mw

久しぶりに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 は巻き上げ「されない」ではなく「されるけど使えない」