JavaScript ES6 Block Scope - let, const
在 ES6 之前,JavaScript 用 var 關鍵字來宣告一個變數,其作用範圍是 function scope,在 ES6 中引入了兩個新的語法 let 和 const 讓你可以宣告塊級作用範圍 (block scope) 的變數。
所謂的 block scope 就是變數的作用範圍只存在兩個大括號 { }
中。
let
let 關鍵字用來宣告一個 block scope 變數。
// global 變數
var a = 1;
{
// block scope 變數
let a = 2;
// 2
alert(a);
// 重複宣告變數,會發生錯誤
// TypeError: Identifier 'a' has already been declared
let a = 3;
}
// 1
alert(a);
另外一個例子:
function varTest() {
var x = 1;
if (true) {
// 同樣的 function scope 變數
var x = 2;
// 2
alert(x);
}
// 2
alert(x);
}
function letTest() {
let x = 1;
if (true) {
// 不一樣的 block scope 變數
let x = 2;
// 2
alert(x);
}
// 1
alert(x);
}
const 常數
const 關鍵字跟 let 類似,也可以用來宣告一個 block scope 變數,不同的是,const 宣告的變數其指向的值不能再被改變。
{
const A = 10;
// 會發生錯誤,常數值不能再被改變
// TypeError: Assignment to constant variable
A = 10;
// 陣列是一個有趣的例子
const ARR = [1, 2];
// 可以改變陣列裡的內容
// 因為 ARR 變數值沒有改變,還是指向同一個陣列
ARR.push(3);
// [1, 2, 3]
console.log(ARR);
// 錯誤,不能改常數值
// TypeError: Assignment to constant variable
ARR = 123;
// 但可以改變陣列裡面的內容
ARR[0] = 4;
// [4, 2, 3]
console.log(ARR);
}
const 還有一個要注意的地方,就是在宣告變數的同時就需要指定值,不然會發生 SyntaxError 錯誤,因為常數的值不能被更改!
// SyntaxError: Missing initializer in const declaration
const foo;
foo = 123;
// 正確的常數宣告方式必須同時賦值
const foo = 123;
一般習慣的 constant variable 命名規則,是全部大寫字母,和可以用底線分隔太長的名稱,例如
CAPITAL_CASING
。Temporal Dead Zone
let 和 const 宣告的變數一樣會被 hoist 提升到 scope 的最上方,但和 var 不一樣的是,在變數宣告之前存取變數會造成 ReferenceError 錯誤,因為用 let 和 const 宣告的變數,在程式執行到變數宣告的地方之前,都會暫時被存放在所謂的 Temporal Dead Zone (暫時性死區),不能被存取。
function foo() {
// 會造成程式錯誤 ReferenceError
console.log(bar);
let bar = 101;
}
IE 瀏覽器從 IE11 開始才有支援 let, const。