ES6出現(xiàn)之前,只有函數(shù)可以形成作用域。而ES6中新增了塊級作用域概念。
let和const命令可以構(gòu)成一個塊級作用域。
1.let
用法類似var,聲明一個塊作用域內(nèi)的變量,注意,塊作用域外無法訪問該變量。用法如下:
// 在if語句中定義塊作用域
var check = true;
if (check) {
let value = 6;
}
console.log(value); //undefined
// 在循環(huán)中定義塊作用域
for(let i =0; i < arr.length; i++) {...}
與var不同之處:
- 不支持“變量提升”;
- 一旦某個變量聲明為let或者const類型,則該變量會綁定該區(qū)域,不受外界影響。例如:
var temp = 1;
if (true) {
console.log(temp); //ReferenceError: 用let聲明的temp變量會綁定該塊作用域
let temp = 2;
}
- 在同一個作用域內(nèi),不允許重復(fù)聲明同一個變量。例如:
if (true) {
let a = 1;
let a = 2; //throw error: Duplicate declaration "a"
}
有了塊級作用域,可以避免內(nèi)層變量覆蓋外層變量,可以讓變量應(yīng)用到更小范圍內(nèi)。
下面讓我們看一道經(jīng)典的閉包問題,思考如何用let解決?例題如下:
var a = [];
for (var i =0; i <10; i++){
a[i] = function(){
console.log(i);
}
}
a[6](); // 10
由于變量i是全局變量,所有每一次循環(huán),新的i值都會覆蓋老的i值,導(dǎo)致最后數(shù)組a的每個元素運(yùn)行結(jié)果都是10。
如果使用let,i變量的作用域范圍只限于塊作用域,即每次循環(huán)的代碼塊,如此一來,最后a[6]()可以返回期望值:6。修改如下:
var a = [];
for (let i =0; i <10; i++){
a[i] = function(){
console.log(i);
}
}
a[6](); // 10
2.const
const用來聲明常量,一旦定義,就不能修改。
這里需要注意,如果const聲明的是對象,那么,變量名指向的是對象地址。所以,對象地址不允許修改,但是,對象的值,是可以修改的。
例如:
const foo = {a: 1};
foo.b = 3; // 正確
foo = {b: 6}; // throw error: "foo" is read-only
3.小結(jié)
塊級作用域的出現(xiàn),幫助解決了很多和變量作用域相關(guān)的問題!讓我們好好享受這個新特性吧!