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】
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/503289.html
標籤:JavaScript
下一篇:# JavaScript中的陣列
