2017-12-01 9 views
0

私はJavaScriptスコープとホイストの基本的な概念を理解しているようでした。このquestion+answerは、その点で私を多く助けました。Javascript:ifブロック内にはどのように吊り上げられますか(ない)?

最近、私は何かに出くわしましたが、それは少し驚きました。次のコードを考えてみましょう:私が学んだことを考えると

var a = 1; 

if (true) { 
    console.log(a); 
    let a = 2; 
} 

console.log(a); 

、私は出力undefined1にそれを期待します。それはUncaught ReferenceError: a is not definedになりますが。

私の理解は、上記のそのコードは、(​​の宣言部は、最も近いinclosingブロックに掲揚されるべきである - この場合、ifある)と等価であるべきである。

var a = 1; 

if (true) { 
    let a; 
    console.log(a); 
    a = 2; 
} 

console.log(a); 

このコード、ちなみに、私が期待する通り、undefined1が生成されます。


私の質問は次のとおりです。

  • は、彼らの最も近い外側のブロック内部の掲揚letで宣言した変数、ありますか?
    • はいの場合、最初のブロックのコードがUncaught ReferenceError: a is not definedになるのはなぜですか?

答えて

3

letconstで宣言した変数に影響を与えるTemporal Dead Zoneと呼ばれる期間は、あります。

this answerを言い換え:

時間的不感帯 - アクセスすることができない変数の中で宣言されている範囲と可変 に入るまでの期間です。

我々は質問から、最初のコードスニペットの時間デッド・ゾーンをマークしていたのであれば、:もちろん

var a = 1; 

if (true) { 
    /* start of the Temporal Dead Zone */ 
    console.log(a); /* code in the Temporal Dead Zone */ 
    /* last line of the Temporal Dead Zone */ 
    let a = 2; /* end of the Temporal Dead Zone */ 
} 

console.log(a); 

documentation、(他のトリッキーな例と一緒に)これを言及

ECMAScript 2015では、letバインディングは変数ホイストの対象外です。つまり、let宣言は現在のexeの先頭に移動しません注意の文脈。初期化の前にブロック内の変数を参照すると、ReferenceErrorが返されます(varで宣言された変数に反して、定義されていない値があります)。変数はブロックの開始から初期化が処理されるまでの「時間的不感帯」にある。

上記の抜粋は、このコードが続きます。

function do_something() { 
console.log(bar); // undefined 
console.log(foo); // ReferenceError 
var bar = 1; 
let foo = 2; 
} 

、明示的に、問題に対処するために:another answerで説明したように - letで宣言された変数が掲揚が、に初期化されていませんそれらの最も近い包囲ブロックの内側にある。連続して可変挙動につながるもの===

+2

これは多言語に共通する振る舞いの本当に奇妙な名前です。 –

+0

あなた自身の質問に答えました。おめでとうございます。 – noChance

+0

まず回答を準備してから質問を投稿してください。 – Mamun

関連する問題