let
let聲明一個變量,與var最不同的地方在于。let擁有塊級作用域,{ } 所包裹住的地方即為一個塊級作用域。
塊級作用域中聲明的變量在外部無法訪問,for循環(huán)中:
for(let i = 0; i<3;i++){
let i = 12
console.log(i)
}
// 輸出3次12
for 循環(huán)有兩個塊級作用域,設(shè)置循環(huán)變量的是父作用域,{}中的是子作用域。
let arr =[]
for (let i = 0;i<3;i++){
console.log(i)
arr.push(function(){
console.log(i)
})
}
console.log(i)
console.log(arr[1]())
// 輸出 0 ,1 ,2
// 輸出 i not defined
// 輸出 1
for (var i = 0; i<3; i++){
console.log(i)
arr.push(function(){
console.log(i)
})
}
console.log(i)
console.log(arr[1]())
// 輸出 0 ,1 ,2
// 輸出3
// 輸出3
let i 只執(zhí)行了一次,但由于let的創(chuàng)建是尊重塊級作用域的,所以每次循環(huán)都是一個新的i,值是i++的結(jié)果,所以閉包引用的i的地址都是不同的。用var聲明的i都是同一個地址,所以閉包的結(jié)果是相同的。
暫時性死區(qū)和不允許重復(fù)聲明
在一個塊級作用域中,let和const聲明的變量就綁定了這個區(qū)域,外部聲明的與之無關(guān)。在塊級作用域中聲明之前引用這兩個變量會報錯,稱之為暫時性死區(qū)。
let a = 1
if (true) {
console.log(a) // a is not defined
let a = 2
console.log(a) // a has already been declared
}
let 和const不存在變量提升,不同于var