let與const命令

居老師的狗子發表於2019-03-12

(需要注意的地方)

1、ES6 新增了let命令,用來宣告變數。它的用法類似於var,但是所宣告的變數,只在let命令所在的程式碼塊內有效。

2、for迴圈還有一個特別之處,就是設定迴圈變數的那部分是一個父作用域,而迴圈體內部是一個單獨的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

上面程式碼正確執行,輸出了 3 次abc。這表明函式內部的變數i與迴圈變數i不在同一個作用域,有各自單獨的作用域。

3、關於變數提升(筆試會給一些程式碼考察)

var命令會發生“變數提升”現象,即變數可以在宣告之前使用,此時值為undefined

而let不存在變數提升,一定要在宣告後使用,否則會報錯。

// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;

4、暫時性死區(temporal dead zone)

ES6 明確規定,如果區塊中存在letconst命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。

總之,在程式碼塊內,使用let命令宣告變數之前,該變數都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。

var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

上面程式碼中,存在全域性變數tmp,但是塊級作用域內let又宣告瞭一個區域性變數tmp,導致後者繫結這個塊級作用域,所以在let宣告變數前,對tmp賦值會報錯。

if (true) {
  // TDZ開始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ結束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

上面程式碼中,在let命令宣告變數tmp之前,都屬於變數tmp的“死區”。

5、不允許重複宣告

let不允許在相同作用域內,重複宣告同一個變數。

6、為什麼需要塊級作用域?

第一種場景,內層變數可能會覆蓋外層變數。

第二種場景,用來計數的迴圈變數洩露為全域性變數。

7、const命令

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

const的作用域與let命令相同:只在宣告所在的塊級作用域內有效。

8、ES6 一共有 6 種宣告變數的方式(有一次筆試遇到過)
var、function、let、const、import、class