幫你精通JS:變量的聲明,舉起與初始化的問(wèn)題
一、首先 JS 的舉起 Hoisting
觀察一下變量自舉的代碼:
- today = "Friday";
- console.log(today);
- // Friday
- var today = "Monday!";
雖然declare的步驟在最后,但是today已經(jīng)順利打印出來(lái),這是因?yàn)閐eclare被hoist到頂部。
- var today; // hoisted declaration
- today = "Friday"; // the original line 1
- console.log(today); // Hello!
- today = "Monday"; // `var` is gone!
JSEngine事先將var舉到頂部執(zhí)行,并初始化值undefined.
接著查看function自舉:
- today();
- // Friday!
- function today() {
- console.log("Friday");
- }
同樣的原理在complie的步驟中,事先將所有的function都解析成AST,因此也就都hoist到了頂部。
繼續(xù)考察function與variable二者的組合。
- today = "Friday";
- printToday();
- // Today is Friday.
- function printToday() {
- console.log(`Today is ${ today }!`);
- }
- var today;
實(shí)際的執(zhí)行是先將function舉起,再將var舉起。
- function printToday() {
- console.log(`Today is ${ today }!`);
- }
- var today;
- today = "Friday";
- printToday();
- // Today is Friday.
二、重復(fù)declare的問(wèn)題
考察下面的代碼:
- let keepMoving = true;
- while (keepMoving) {
- let value = Math.random();
- if (value > 0.5) {
- keepMoving = false;
- }
- }
乍一看,似乎每次循環(huán)都會(huì)執(zhí)行`let value = Math.random();`,但實(shí)際上只執(zhí)行一次,執(zhí)行一次后,declare 的部分將會(huì)從代碼中移除。
三、變量初始化的問(wèn)題TDZ問(wèn)題
除了var之外,let也將舉起,只是不會(huì)被初始化:
- var studentName = "Timy";
- {
- console.log(studentName);
- // ???
- let studentName = "Smith";
- console.log(studentName);
- // Smith
- }
第一個(gè)console不會(huì)輸出 "Timy"而是會(huì)報(bào)錯(cuò),說(shuō)明let也被舉起,只是沒(méi)有被初始化。
解決此問(wèn)題的方法就是將所有的let,const等全部都寫(xiě)到頂部。