(需要注意的地方)
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 明確規定,如果區塊中存在let
和const
命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。
總之,在程式碼塊內,使用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
命令相同:只在宣告所在的塊級作用域內有效。