ENCA 7日目: Temporal Dead Zone (TDZ) をやめたい(未定)
var
と let
/const
の違い
ES2015 から変数宣言に let
/const
が導入されました。レガシーな var
と比べてブロックスコープであり、同一スコープでの再宣言ができないようになっています。
また let
/const
には変数の初期化(宣言)前にアクセスすると ReferenceError
を投げる仕様があります。これを Temporal Dead Zone (TDZ) と呼びます。
console.log(foo); // undefined
var foo = "foo";
console.log(foo); // throws ReferenceError
let foo = "foo";
これら仕様によってバグの発生を抑制してくれています。
TDZ によるパフォーマンスの問題
TDZ は実行順(時間)に依存していることから Temporal という形容詞が使われています。例えば以下のコードは問題なく実行できます。
function showFoo() {
console.log(foo); // "foo"
}
const foo = "foo";
showFoo();
つまり TDZ に引っかかるかどうかを静的解析することは困難であり、基本的に実行時チェックされています。よって var
よりも多少パフォーマンスが悪くなってしまいます。これは通常問題にならないため積極的に let
/const
を採用したほうが良いですが、スコープが大きい場合は無視できない場合があります。
実際に TypeScript の公式コンパイラである tsc において、行数が4桁オーダーの大きい函数内でのみ、あえて var
が使われています。
これについては mozaic.fm で JavaScriptCore を実装されている Constellation さんの話が参考になるかと思います(ES2015 を実装していた時の話であることに留意してください)。
TDZ をやめたい
2023年9月の会議で TDZ が効果的かどうか議論されました。
Babel や TypeScript で ES5 ターゲットに出力するときに var
に変換されますが、TDZ を無視した変換となっています[1]。つまりこの機能を取り除いて、初期化前にアクセスした際には単に undefined
としてしまっても、Web ディベロッパー的に問題ないと思われます。
この議論は将来また提案として進めるかもしれないという扱いになっています。
-
Babel はオプションで TDZ が有効にできるようです。 ↩︎
Discussion