ES6: let, const, Block-Level Scope
28 Oct 2016let, const, var, function declaration, block-level scope, hoisting 相關筆記。
let
變數宣告,功能類似 var
,但有以下特性
- block-level scope(塊級作用域)
- 有 hoising(變量提升),可參考這篇文章
- temporal dead zone, TDZ:宣告後才能使用
- 不允許重複宣告
const
常數宣告,有以下特性
- 對於 primitives 的變數,宣告後就不能改變值,因此宣告時一定要設值,並且變數名指向資料;對於非 primitives 的變數,變數名指向資料所在的 address,不可重新賦值但可改變該 address 的內容
- block-level scope
- 有 hoising,可參考這篇文章
- temporal dead zone, TDZ
- 不允許重複宣告
Block-Level Scope 塊級作用域
javascript 只有 global 和 function 兩種 scope,意即若使用 var
與 function
做變數宣告,只能將變數的活動範圍限制在全域或函數中,這可能會產生非預期的結果。
例如:使用 var
宣告 i
當成 for loop 的 counter,當 i 離開 for loop 後,仍可被存取,因此得到 a[6]()
為 10。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
};
}
a[6](); // 10
改用 ES6 即可解決這樣的問題,let(和 const) 有 block-level scope 特性,離開大括號({…}) 的範圍後便失效。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
};
}
a[2](); // 2
Top-Level LexicalEnvironment
Top-Level LexicalEnvironment 在瀏覽器環境指的是 window,在 node 指的是 global。在 ES5 之中,Top-level LexicalEnvironment 的屬性與 global variable 的屬性是相同的。
var a = 6; // global variable
console.log(window.a); // 6,a 屬於 window 的屬性
在 ES6 中使用 let
、const
、class
所宣告的 global 變數,不屬於 Top-level LexicalEnvironment 的屬性。但為了兼容,使用 var
和 function
宣告的 global 變數仍維持屬於 Top-level LexicalEnvironment 的屬性。
例如:a 由 var
宣告為 global 變數,為 Top-level LexicalEnvironment(在此為 window) 的屬性;b 由 let
宣告為 global 變數,不為 Top-Level LexicalEnvironment 的屬性,得到 undefined。
var a = 1;
window.a; // 1
let b = 1;
window.b; // undefined
References
這篇文章的原始位置在這裡-ES6 - let, const, Block-Level Scope
由於部落格搬遷至此,因此在這裡放了一份,以便閱讀;部份文章片段也做了些許修改,以期提供更好的內容。