iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
Modern Web

[學習筆記] 邊學邊寫 JavaScript 30天系列 第 24

[學習筆記] 邊學邊寫 JavaScript 30天 (24):Hoisting II

  • 分享至 

  • xImage
  •  

今天內容

  • 重新理解昨天的小練習
  • let 與 const 的 Hoisting
  • TDZ:Temporal Dead Zone

筆記

  • 以昨天最後說的規則加入執行環境的角度來重新理解
    小練習程式碼

    var a = 1;
    function test(){
      console.log("1.", a);     // undefined
      var a = 7;
      console.log("2.", a);     // 7
      a++;
      var a;
      inner();
      console.log("4.", a);     // 30
      function inner(){
        console.log("3.", a);   // 8
        a = 30;
        b = 200;
      }
    }
    test();
    console.log("5.", a);       // 1
    a = 70;
    console.log("6.", a);       // 70
    console.log("7.", b);       // 200
    

    執行環境 (放一張有行數的原始碼圖片)

    執行順序 (解說字的顏色對應到執行環境圖的配色)

  • let 與 const 的 Hoisting (以let舉例)

    console.log(a)
    let a = 10    //ReferenceError: Cannot access 'a' before initialization
    

    上面看起來let沒有Hoisting,再加個function看看

    let a = 10
    function test() {
      console.log(a)
      let a = 30  //ReferenceError: Cannot access 'a' before initialization at test
    }
    test()
    

    也一樣出現報錯,根據昨天理解的規則來看:沒有Hoisting表示沒有在function test()對a初始化,那不就應該要根據scope chain 往上層找到global的 a=10 來做印出嗎?但還是出現報錯。
    所以let還是有提升,只是提升的方式和var不同。

  • TDZ:Temporal Dead Zone
    let不會將變數先做初始化,所以在賦值之前都不能做存取它這件事,不然就會報錯。而在存取它到賦值的這段期間就稱做是TDZ(是一個為了解釋let與 const的Hoisting行為所提出的一個名詞。)
    根據昨天的Hoisting作法,可以想成下面這樣:

    let a = 10
    function test() {
      let a            
      //在進到test()執行環境一樣有Hoisting,只是沒有像var將變數初始化undefined。
      .
      .
      .
      console.log(a)  //報錯 -> 在TDZ這個期間要存取還沒被賦值的a,就會報錯。
      .
      .
      .
      a = 30  
      //從進入test()執行環境開始 到出現賦值以前都是TDZ。
    }
    test()
    

    TDZ是一種期間(不是空間):從進到function test()執行環境 到let a = 30賦值之前,都是TDZ 不能做存取,不然會報錯。中間可能有其他code會執行(上述程式碼以...代替),到執行a = 30賦值這ㄧ行,所以才會說是時間。


參考資料


上一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (23):Hoisting I
下一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (25):Closure
系列文
[學習筆記] 邊學邊寫 JavaScript 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言