ES6 - let, const, Block-Level Scope

ES6 - let, const, Block-Level Scope

let, 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,意即若使用 varfunction 做變數宣告,只能將變數的活動範圍限制在全域或函數中,這可能會產生非預期的結果。

例如:使用 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 中使用 letconstclass 所宣告的 global 變數,不屬於 Top-level LexicalEnvironment 的屬性。但為了兼容,使用 varfunction 宣告的 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
張貼留言