1 以下代碼執行後,控制臺中的輸出內容為? for (let i = 0; i < 3; i++) { setTimeout(() => { console.log(i); }); } for (var j = 0; j < 3; j++) { setTimeout(() => { console. ...
1 以下代碼執行後,控制臺中的輸出內容為?
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
});
}
for (var j = 0; j < 3; j++) {
setTimeout(() => {
console.log(j);
});
}
2 以下代碼執行後,控制臺中的輸出內容為?
if (!("a" in window)) {
var a = 1;
}
if (!("b" in window)) {
let b = 1;
}
console.log(window);
console.log(a);
console.log(b);
3 以下代碼執行後,控制臺中的輸出內容為?
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 聲明的變數沒有塊級作用域,在 for 迴圈中使用 var 聲明迭代變數 j 會導致所有 setTimeout 中使用的 j 指向同一個變數,而 setTimeout 屬於巨集任務,執行的時機在正常任務隊列之後,即此處 for 迴圈退出之後開始執行,此時迭代變數保存的是導致迴圈退出的值 3,因此所有 setTimeout 的回調函數都會輸出 3
而 let 聲明迭代變數時,JS 引擎會為每個迭代迴圈聲明一個新的迭代變數,每個 setTimeout 引用的都是不同的變數實例,所以最後輸出 0 1 2
2、答案:undefined 報錯:Uncaught ReferenceError: b is not defined
var 聲明的變數沒有塊級作用域,並且存在變數提升,因此該題代碼等價於:
var a;
if (!("a" in window)) {
a = 1;
}
此時 a 為全局變數,而由 var 聲明的全局變數會成為 window 的屬性,因此 if 語句塊中的代碼不會執行,所以 console.log(a)
輸出 undefined
而 let 聲明的變數存在塊級作用域的概念,所以 let b 不會成為全局變數,即使其成為全局變數,也不會成為 window 的屬性,因為 let 聲明的全局變數不會成為 window 的屬性,所以在 console.log(b)
所在的作用域(全局)中,未聲明變數 b,因此會報錯:Uncaught ReferenceError: b is not defined
3、答案:0 1 0
var 聲明的變數不存在塊級作用域,但是存在局部作用域,此題中變數 i 的作用域為 fn 函數作用域
每次調用fn
都會形成一個閉包,不同閉包之間是獨立的不會互相干擾
閉包會將 i 的值保存下來,多次調用 fn() 返回的函數會修改 i 的值
所以最終會輸出:0 1 0
公眾號【今天也要寫bug】