|
|
|
|
|
在前端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記錄到控制臺。查看演示
代碼片段分兩個階段執(zhí)行。
階段1
for()
迭代 3 次。在每次迭代期間,都會log()
創(chuàng)建一個新函數,該函數捕獲變量i
。setTimout()
計劃log()
在 1000 毫秒后執(zhí)行。
當for()
循環(huán)完成時,i
變量具有值3
。
階段2
第二階段發(fā)生在 1000 毫秒后:
setTimeout()
執(zhí)行預定的log()
功能。log()
讀取變量的當前值i
,即3
,并記錄到控制臺3
。
這就是為什么333
被記錄到控制臺了。
挑戰(zhàn)一下:如何在經過 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
。
挑戰(zhàn)一下:如何修復log()
函數以返回具有實際count
值的消息?
總結
本文收集了5個有關javascript閉包的面試問題,通過針對這些問題的解釋,你對閉包概念的理解應該會更進一步。
相關文章