Johnson Mao

Day.27 「var 成為時代的眼淚!」 —— ES6 區塊作用域 與 提升

「var 成為時代的眼淚!」 —— ES6 區塊作用域 與 提升

之前已經介紹了 var函式作用域,今天來更仔細的介紹 ES6 新增的 letconst以及與它們相關的區塊作用域

#區塊作用域

函式作用域有點像,一樣都是作用域內沒有的變數可以往外獲取變數,不一樣的是更嚴格謹慎,不只限制在函式上了,連 if elsewhilefor 這些循環語句都有限制不能從外往內取,稱為區塊作用域Block Scope)。

以常見的 var 全域汙染為例:

複製成功!
for (var i = 0; i < 3; i++) {}
console.log( i );    // 3,成功在 for 迴圈外面獲取到 for 迴圈內的 i = 3

for (let a = 0; a < 3; a++) {}
console.log( a );    // 報錯, a is not defined

#let 的特性

let 跟我們常用的 var 用法非常相似,但也是有不同的地方!

  • let 不可重複宣告

    • 使用 var 重複宣告不會報錯,只會覆蓋掉

      複製成功!
      var name = "毛毛";
      var name = "小黃";  // 使用 var 重複宣告不會報錯,只會覆蓋掉
      
    • 使用 let 重複宣告會報錯

      複製成功!
      let name = "毛毛";
      let name = "小黃";  // 使用 let 重複宣告會報錯
      
  • 區塊作用域

    • 使用 var 容易汙染全域作用域

      複製成功!
      for (var i = 0; i < 3; i++) {}
      console.log( i );    // 成功在 for 迴圈外面獲取到 i = 3
      
    • 使用 let 則能讓變數限制在區塊內

      複製成功!
      for (let i = 0; i < 3; i++) {}
      console.log( i );    // 報錯, i is not defined
      
  • 變數提升效果不同

    • 使用 var 會自動提升,並顯示未定義 undefined

      複製成功!
      console.log(name);  // undefined
      var name = "毛毛";
      
    • 使用 let 宣告比較嚴謹,會直接報錯(也就是俗稱的死區),讓 debug 效率變高

      複製成功!
      console.log(name);  // 報錯
      let name = "毛毛";
      

#const 的特性

  • 必須要賦初始值

    複製成功!
    const PI;  // 報錯
    
  • 常數不能修改

    複製成功!
    const PI = 3.14159265;
    PI++  // 報錯
    
  • 一樣也具有區塊作用域

  • 對陣列或物件內的屬性做修改,並不會報錯

    • 因為我們知道物件型別存的是參考(地址),只要 Stack 值不變就不會報錯
      複製成功!
      const person = { name: "毛毛", gender: "男" };
      person.name = "鮭魚";
      person.age = 27;
      console.log( person );  // { name: "鮭魚", gender: "男", age: 27 }
      

#總結

會使用 letconst 後,就比較少使用到 var 了,在宣告物件型別不會主動修改值得變數都會建議使用 const 來宣告!這樣比較不容易變動到變數而出現意想不到的 bug。

回首頁