1 以下代碼執(zhí)行后闸氮,控制臺(tái)中的輸出內(nèi)容為教沾?
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
});
}
for (var j = 0; j < 3; j++) {
setTimeout(() => {
console.log(j);
});
}
2 以下代碼執(zhí)行后授翻,控制臺(tái)中的輸出內(nèi)容為?
if (!("a" in window)) {
var a = 1;
}
if (!("b" in window)) {
let b = 1;
}
console.log(window);
console.log(a);
console.log(b);
3 以下代碼執(zhí)行后巡语,控制臺(tái)中的輸出內(nèi)容為淮菠?
function fn() {
var i = 0;
return function () {
console.log(i++);
};
}
var f1 = fn();
var f2 = fn();
f1();
f1();
f2();
1、答案:0 1 2 3 3 3
解析:var 聲明的變量沒有塊級(jí)作用域理澎,在 for 循環(huán)中使用 var 聲明迭代變量 j 會(huì)導(dǎo)致所有 setTimeout 中使用的 j 指向同一個(gè)變量,而 setTimeout 屬于宏任務(wù)糠爬,執(zhí)行的時(shí)機(jī)在正常任務(wù)隊(duì)列之后举庶,即此處 for 循環(huán)退出之后開始執(zhí)行,此時(shí)迭代變量保存的是導(dǎo)致循環(huán)退出的值 3镀琉,因此所有 setTimeout 的回調(diào)函數(shù)都會(huì)輸出 3
而 let 聲明迭代變量時(shí)蕊唐,JS 引擎會(huì)為每個(gè)迭代循環(huán)聲明一個(gè)新的迭代變量替梨,每個(gè) setTimeout 引用的都是不同的變量實(shí)例装黑,所以最后輸出 0 1 2
2恋谭、答案:undefined 報(bào)錯(cuò):Uncaught ReferenceError: b is not defined
var 聲明的變量沒有塊級(jí)作用域挽鞠,并且存在變量提升,因此該題代碼等價(jià)于:
var a;
if (!("a" in window)) {
a = 1;
}
此時(shí) a 為全局變量材义,而由 var 聲明的全局變量會(huì)成為 window 的屬性狮杨,因此 if 語句塊中的代碼不會(huì)執(zhí)行,所以 console.log(a)
輸出 undefined
而 let 聲明的變量存在塊級(jí)作用域的概念清寇,所以 let b 不會(huì)成為全局變量华烟,即使其成為全局變量持灰,也不會(huì)成為 window 的屬性,因?yàn)?let 聲明的全局變量不會(huì)成為 window 的屬性喂链,所以在 console.log(b)
所在的作用域(全局)中椭微,未聲明變量 b盲链,因此會(huì)報(bào)錯(cuò):Uncaught ReferenceError: b is not defined
3、答案:0 1 0
var 聲明的變量不存在塊級(jí)作用域本慕,但是存在局部作用域侧漓,此題中變量 i 的作用域?yàn)?fn 函數(shù)作用域
每次調(diào)用fn
都會(huì)形成一個(gè)閉包,不同閉包之間是獨(dú)立的不會(huì)互相干擾
閉包會(huì)將 i 的值保存下來鉴象,多次調(diào)用 fn() 返回的函數(shù)會(huì)修改 i 的值
所以最終會(huì)輸出:0 1 0
公眾號(hào)【今天也要寫bug】