初期化される前に値let
にアクセスすると、と呼ばれるものが原因で問題が発生することがあると聞きました。const
ReferenceError
時間的デッドゾーン。
時間的デッドゾーンとは何ですか? それはスコープやホイストとどのように関係していますか? また、どのような状況で発生しますか?
ベストアンサー1
let
および には、const
次の 2 つの大きな違いがありますvar
。
- 彼らですブロックスコープ。
- 宣言される前に にアクセスすると
var
、結果は になります。宣言される前にまたはにundefined
アクセスすると、次の結果がスローされます。let
const
ReferenceError
console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization
var aVar = 1;
let aLet = 2;
これらの例から、let
宣言(およびconst
、同じように動作する)は、吊り上げられたaLet
値が割り当てられる前には存在しないように見えるためです。
しかし、そうではないlet
。const
はホイストされます ( var
、およびclass
などfunction
) が、スコープに入ってから宣言されるまでの間にアクセスできない期間があります。この期間は時間的デッドゾーン(TDZ)です。
TDZはaLet
、宣言した、 それよりも割り当てられた:
// console.log(aLet) // Would throw ReferenceError
let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10
この例では、let
がホイストされることを示しています。
let x = "outer value";
(function() {
// Start TDZ for x.
console.log(x);
let x = "inner value"; // Declaration ends TDZ for x.
}());
クレジット:時間的デッドゾーン(TDZ)の謎を解明。
x
内部スコープでアクセスすると、依然として が発生しますReferenceError
。let
がホイストされない場合は、 がログに記録されますouter value
。
TDZ はバグをハイライトするのに役立つので便利です。値が宣言される前にその値にアクセスすることは、ほとんど意図的ではありません。
TDZ はデフォルトの関数引数にも適用されます。引数は左から右に評価され、各引数は割り当てられるまで TDZ 内にあります。
// b is in TDZ until its value is assigned.
function testDefaults(a = b, b) { }
testDefaults(undefined, 1); // Throws ReferenceError because the evaluation of a reads b before it has been evaluated.
TDZはデフォルトでは有効になっていません。バベルトランスパイラ。「高コンプライアンス」モードをオンにして、再生産es6.spec.blockScoping
CLI またはライブラリとして使用するには、フラグを指定します。
推奨される追加資料:TDZの謎を解明そしてES6 Let、Const、そして「Temporal Dead Zone (TDZ)」の詳細。