簡體   English   中英

雙重聲明:如何讓吊裝在循環中工作?

[英]Double let declaration: How does let hoisting work in for loops?

鑒於以下簡化代碼,為什么我會得到一個ReferenceError?

    function foo(n){
        for (let i = 0; i < n; i++) {       
            console.log(i);
            let i = 10;
        }
    }

    foo(4);

// OUTPUT: ReferenceError: i is not defined

let變量應該像所有其他類型的聲明一樣被提升。 因此,在此代碼中, i被聲明兩次。 首先,在初始化關閉和第二個for循環本身。

為什么i is not defined此輸出i is not defined而不是Identifier 'i' has already been declaredIdentifier 'i' has already been declared

JS如何閱讀上面的代碼?

let變量應該像所有其他類型的聲明一樣被提升。

let變量沒有懸掛,不同var變量和函數和類的聲明。 const變量是相同的。

變量在到達聲明它的行之前不會存在。

但是 ,在到達聲明之前,您無法訪問相關范圍中的變量。 這有點無益,被稱為時間死區 有用的2ality博客

這很有用,因為在聲明變量之前訪問它幾乎總是一個錯誤。 或者,至少,它是令人困惑的,並會在您重構時導致錯誤。

function foo(n){
    for (let i = 0; i < n; i++) {       
        // i cannot be accessed
        let i = 10;
        // i is set to 10
    }
}

foo(4);

至於為什么它不是“已經聲明的標識符”錯誤, for循環標頭中聲明的變量的范圍是與塊中聲明的變量的單獨變量。 這段代碼中基本上有三個范圍:外部的一個,一個在for循環標題中開始,另一個在用{}包圍的塊中開始。

下面發生的是JavaScript在同一個for循環中看到兩個不同級別的塊范圍。

第一個是在循環的初始化子句( let i = 0; )中聲明循環內部的第二個。

這是第一次運行代碼時發生的情況:

  • let 初始化子句i = 0 ;
  • let for-loop 內部i is set to undefined

在此輸入圖像描述

當for循環命中console.log(i)它在循環中找到let i的聲明,它覆蓋先前聲明的並分配了let i (在初始化子句中)。

由於每次提升, letconst被聲明但未初始化( undefined ),它會拋出一個ReferenceError。

累計到MDN:

function test(){
  var foo = 33;
  if (true) {
   let foo = (foo + 55); // ReferenceError
  }
}
test();

由於詞法作用域,表達式(foo + 55)中的標識符“foo”評估為if塊的foo,而不是值為33的上覆變量foo。在那一行中,if塊的“foo”已經已經在詞法環境中創建,但尚未達到(並終止)其初始化(這是語句本身的一部分):它仍然處於時間死區。

這意味着如果循環變量在您的示例中是“讀取”,(在您的情況下是console.log,您無法將其分配給同名的var,就像在“死區”中一樣)

MDN ref: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let (在臨時死區下

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM