之前已經介紹了 var
與函式作用域,今天來更仔細的介紹 ES6 新增的 let
、 const
以及與它們相關的區塊作用域
#區塊作用域
與函式作用域有點像,一樣都是作用域內沒有的變數可以往外獲取變數,不一樣的是更嚴格謹慎,不只限制在函式上了,連 if else
、 while
、 for
這些循環語句都有限制不能從外往內取,稱為區塊作用域(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 }
- 因為我們知道物件型別存的是參考(地址),只要 Stack 值不變就不會報錯
#總結
會使用 let
與 const
後,就比較少使用到 var
了,在宣告物件型別或不會主動修改值得變數都會建議使用 const
來宣告!這樣比較不容易變動到變數而出現意想不到的 bug。