|
|
|
|
|
|
在前端JavaScript面試中,閉包是經常被問到的概念。在本文中,我收集了關于JavaScript閉包的5個面試問題,你能否回答?
1、下面哪個函數訪問外部范圍變量?
A:
let countClicks = 0;
button.addEventListener('click', function clickHandler() {
countClicks++;
});
B:
const result = (function immediate(number) {
const message = `number is: ${number}`;
return message;
})(100);C:
setTimeout(function delayedReload() {
location.reload();
}, 1000);答案
clickHandler countClicks 從外部范圍訪問變量。
immediate 不從外部范圍訪問任何變量。
delayedReload location從全局范圍(也就是最外層范圍)訪問全局變量。
所以答案是:A
2、以下代碼片段在控制臺輸出的是什么記錄?
(function immediateA(a) {
return (function immediateB(b) {
console.log(a); // 記錄什么?
})(1);
})(0);答案
0被記錄到控制臺。查看演示
immediateA用參數調用0,因此a參數是0。
immediateB是嵌套在aimmediateA函數中的函數,是一個從外部范圍immediateA捕獲變量的閉包,其中a為0。因此console.log(a)等于0。
3、以下代碼片段控制臺記錄什么?
let count = 0;
(function immediate() {
if (count === 0) {
let count = 1;
console.log(count); // 記錄什么?
}
console.log(count); // 記錄什么?
})();
答案
1和0記錄到控制臺。查看演示
第一條語句let count = 0聲明了一個變量count。
immediate()是一個從外部范圍捕獲變量count的閉包。immediate()函數范圍內count是0。
但是,在條件內部,另一個let count = 1聲明了一個局部變量coun,它把外部范圍的count覆蓋。第一個console.log(count)日志是1。
第二個console.log(count)日志是0,因為這里count的變量是從外部范圍訪問的。
4、以下代碼片段控制臺記錄什么?
for (var i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // 記錄什么?
}, 1000);
}答案
333記錄到控制臺。查看演示
代碼片段分兩個階段執行。
階段1
for()迭代 3 次。在每次迭代期間,都會log()創建一個新函數,該函數捕獲變量i。setTimout()計劃log()在 1000 毫秒后執行。
當for()循環完成時,i變量具有值3。
階段2
第二階段發生在 1000 毫秒后:
setTimeout()執行預定的log()功能。log()讀取變量的當前值i,即3,并記錄到控制臺3。
這就是為什么333被記錄到控制臺了。
挑戰一下:如何在經過 1 秒后將此示例修復為記錄0、1值?
5、以下代碼片段控制臺記錄什么?
function createIncrement() {
let count = 0;
function increment() {
count++;
}
let message = `Count is ${count}`;
function log() {
console.log(message);
}
return [increment, log];
}
const [increment, log] = createIncrement();
increment();
increment();
increment();
log(); // 記錄的是什么?答案
Count is 0被記錄到控制臺。查看演示
increment()函數已被調用 3 次,有效地遞增count的值到3。
message變量存在于createIncrement()函數的范圍內。其初始值為Count is 0。但是,即使count變量已經增加了幾次,message變量總是保持不變Count is 0。
log()函數是一個從createIncrement()作用域捕獲message變量的閉包。console.log(message)記錄到控制臺是Count is 0。
挑戰一下:如何修復log()函數以返回具有實際count值的消息?
總結
本文收集了5個有關javascript閉包的面試問題,通過針對這些問題的解釋,你對閉包概念的理解應該會更進一步。
相關文章
