LoginSignup
11

More than 3 years have passed since last update.

Temporal dead zoneと死の秘宝(var/const/let)

Last updated at Posted at 2019-12-15

ChromeやNodeJSのJavascriptコンソール画面で動作確認する場合、
以下の様に間違ってエラーになってしまうことがあります。

const obj = JSON.parse(""); // JSON形式じゃない文字列を指定
// Uncaught SyntaxError: Unexpected end of JSON input

JSON形式の文字列で指定するところに空文字を指定した場合ですが、Uncaught SyntaxErrorとなってしまいます。

じゃあ間違えたのだからと訂正して再度実行すると

const obj = JSON.parse("[]"); // JSON形式の文字列を指定
// Uncaught SyntaxError: Identifier 'obj' has already been declared

既に宣言済みなのでエラーとなります。

それでは、既に宣言済みなら変数が存在するのだと思って参照してみると

console.log(obj); 
// Uncaught ReferenceError: obj is not defined

宣言されていないとエラーとなります。

グローバルに変数が残っているかなと思ってdeleteを実行しても消えている様子は無いです。

delete obj;
// false
const obj = JSON.parse("[]");
// Uncaught SyntaxError: Identifier 'obj' has already been declared

MDNのlet変数やconst変数の説明を見てみるとTemporal dead zoneの存在について紹介されています。

undefined の値で始まる var 変数と異なり、 let 変数は定義が評価されるまで初期化されません。変数を宣言より前で参照することは ReferenceError を引き起こします。ブロックの始めから変数宣言が実行されるまで、変数は "temporal dead zone" の中にいるのです。

どうやら、宣言されたconstlet変数はTemporal dead zoneの中に残ってしまっていて参照できない状態になっているようです。

エラーが発生するなどして変数の初期化が行われなかった場合、letconstについてはTemporal dead zoneに変数があるため、宣言はされているが、参照出来ない状態となるらしいです。この状態だと変数を再使用することは出来なくなってしまいます。

varの場合だと変数を宣言する前に呼び出すとundefinedが取得されます。

console.log(pizza);
var pizza = 'Deep Dish 🍕🍕🍕';
// undefined

letの場合だと変数を宣言する前に呼び出すとUncaught ReferenceErrorとなり変数が取得できません。

console.log(pizza);
let pizza = 'Deep Dish 🍕🍕🍕';
// Uncaught ReferenceError: Cannot access 'pizza' before initialization

変数pizzaはTemporal dead zoneから取り出せずもう使用することは出来なくなってしまいます。

対応策としては、
リロードなどをして最初から実行し直すか、
もしくは、varを使うか、

var obj = JSON.parse("");
// Uncaught SyntaxError: Unexpected end of JSON input
var obj = JSON.parse("");
// Uncaught SyntaxError: Unexpected end of JSON input

もしくはスコープを指定するか、

{
  const obj = JSON.parse("");
}

もしくはletを使っていったん宣言だけすれば最初にundefinedがセットされます。

let obj;
// undefined
obj = JSON.parse("");
// Uncaught SyntaxError: Unexpected end of JSON input
obj = JSON.parse("");
// Uncaught SyntaxError: Unexpected end of JSON input

闇の魔術とはちょっと違うかも知れないけれど、Temporal dead☠️ zoneの呼び方が闇っぽいのでここに載せておきました。

と思っていたら、The Temporal Dead Zone and the Deathly Hallows(Temporal Dead Zoneと死の秘宝)と呼んでいる記事があったのでタイトルも合わせて変えました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11