1. 程式人生 > >es6學習之路(2):作用域,不存在變數提升,避免暫時性死區,與全域性物件的屬性脫鉤

es6學習之路(2):作用域,不存在變數提升,避免暫時性死區,與全域性物件的屬性脫鉤

1、ES6 新增了let命令,用來宣告變數。它的用法類似於var.

       const宣告一個只讀的常量。一旦宣告,常量的值就不能改變.const宣告的變數不得改變值,這意味著, const 一旦宣告變數,就必須立即初始化,不能留到以後賦值。

    這2個都是在所在的程式碼塊內有效。意味著他們有自己的作用域。而且,不存在變數,所以存在“暫時性死區”的問題。

    ES6 明確規定,如果區塊中存在let和const命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變
    量,就會報錯。
    總之,在程式碼塊內,使用 let 命令宣告變數之前,該變數都是不可用的。這在語法上,稱為 “ 暫時性死區 ” ( temporal dead zone ,簡稱 TDZ )

下面的程式碼如果使用var,最後輸出的是 10 。
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10
如果使用let,宣告的變數僅在塊級作用域內有效,最後輸出的是 6 。
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6
console.log(foo); //  輸出 undefined
console.log(bar); //  報錯 ReferenceError
var foo = 2;
let bar = 2;

2、未宣告的全域性變數,自動成為全域性物件window的屬性,這被認為是 JavaScript 語言最大的設計敗筆之一。這樣的設計帶來了兩個很大的問題,首先是沒
法在編譯時就報出變數未宣告的錯誤,只有執行時才能知道,其次程式設計師很容易不知不覺地就建立了全域性變數(比如打字出錯)。另一方面,從語義
上講,語言的頂層物件是一個有實體含義的物件,也是不合適的。
ES6 為了改變這一點,一方面規定,為了保持相容性,var命令和function命令宣告的全域性變數,依舊是全域性物件的屬性;另一方面規定,let命
令、const命令、class命令宣告的全域性變數,不屬於全域性物件的屬性。也就是說,從 ES6 開始,全域性變數將逐步與全域性物件的屬性脫鉤。
var a = 1;
//  如果在 Node 的 REPL 環境,可以寫成 global.a
//  或者採用通用方法,寫成 this.a
window.a // 1
let b = 1;
window.b // undefined
上面程式碼中,全域性變數a由var命令宣告,所以它是全域性物件的屬性;全域性變數b由let命令宣告,所以它不是全域性物件的屬性,返回undefined。