- let 的「創(chuàng)建」過(guò)程被提升了税产,但是初始化沒(méi)有提升,不允許重復(fù)聲明。
- var 的「創(chuàng)建」和「初始化」都被提升了辟拷。
- TDZ 暫時(shí)死區(qū)撞羽,就是不能在初始化之前,使用變量衫冻。
let x = 'global'
{
console.log(x) // Uncaught ReferenceError: x is not defined
let x = 1
}
console.log(x)
報(bào)錯(cuò)了诀紊,說(shuō)x
沒(méi)有被定義,說(shuō)明x
指向的是let x = 1
聲明的x
隅俘,而不是塊代碼外的x
變量
這就說(shuō)明了let x = 1
聲明提升了邻奠,你覺(jué)得代碼應(yīng)該是這樣的:
let x = 'global'
{
let x
console.log(x) // Uncaught ReferenceError: x is not defined
x = 1
}
因?yàn)?code>let x不像var x
一樣,聲明提升隨便初始化為undefined
为居,這樣理解沒(méi)毛病碌宴,可以接受。但是看到下面這個(gè)例子后颜骤,我就懵了唧喉。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
按我們上面的理解,代碼執(zhí)行應(yīng)該是這樣的:
var tmp = 123;
if (true) {
let tmp;
tmp = 'abc'; // ReferenceError
}
那么為什么會(huì)報(bào)錯(cuò)呢忍抽,其實(shí)是我們理解錯(cuò)了。
let tmp
聲明確實(shí)被提升了董朝,但同時(shí)變量tmp
也進(jìn)入了暫時(shí)性死區(qū)鸠项,直到真的執(zhí)行到let tmp
時(shí),變量tmp
才被初始化為undefined
子姜,這時(shí)候我們才可以使用變量tmp
下面這段代碼就很好理解TDZ 暫時(shí)死區(qū)
if (true) {
// TDZ開(kāi)始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結(jié)束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}