i_amaiの雑記

お金稼ぎが目的のブログです

Temporal Dead Zoneってなんぞや

最近個人的に「何それよく分からん」となったJavaScriptについてのメモ。

間違ってたら教えてください。

hoist と TDZ

なんか厨二センスあふれるこのフレーズは、You Don't Know JSの著者、Kyle Simpson氏のツイートから。

hoistしてなかったら2回目のconsole.log(x)では2が出力されんだろ?って言ってるんだけど、まずhoistの意味が分からんかった。

で、調べた。

console.log(x); // undefined
var x = 2;
{
  console.log(x); // ReferenceError: x is not defined
  let x = 3;
}

前者のconsole.log(x)はエラーにならない。後者のconsole.log(x)はエラーになる。

letが宣言されたブロックの中では、ブロックの最初にlet宣言された変数を走査し、それらをundefinedとしてインスタンス化する。これを巻き上げ(hoist)と呼ぶ。

letの場合は巻き上げた時点(ブロックの最初)から実際に変数が初期化されるまでの間を特にTemporal Dead Zoneと呼んでいる。Temporal Dead Zone中にその変数を参照しようとするとエラーになる。

ちなみに、

let u = undefined;
console.log(u); // undefined

この場合は同じundefinedでもエラーにならない。つまり、変数の初期化フラグをJavaScript Engineが内部的に管理しているということなのかな?

varの場合も巻き上げは行われるが、その宣言がブロックの中だろうが、すべてがプログラム実行の最初に走査されて、undefinedとしてインスタンス化される。これは適当なIDE等で変数を色んな場所で宣言したコードを用意し、1行目にブレークポイントをおいてデバッグしてみればすぐ分かる。

f:id:i_amai:20190302231236p:plain
VS Codeデバッグ

その他、TDZに関する動作のあれこれは以下のページを参照した。まだ全部読んでないけど。

jsrocks.org