Quantcast
Viewing all articles
Browse latest Browse all 8868

Temporal dead zoneと消えない変数

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

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

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

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

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

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

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

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

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

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

deleteobj;// falseconstobj=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の中に残ってしまっていて参照できない状態になっているようです。

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

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

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

{constobj=JSON.parse("");}

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

letobj;// undefinedobj=JSON.parse("");// Uncaught SyntaxError: Unexpected end of JSON inputobj=JSON.parse("");// Uncaught SyntaxError: Unexpected end of JSON input

DevToolやNodeJSのコンソール画面で操作するときにぐらいしか意識しないかと思いますが。

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


Viewing all articles
Browse latest Browse all 8868

Trending Articles