您好,登錄后才能下訂單哦!
小編給大家分享一下JavaScript中關(guān)于閉包的面試題有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
每個 JavaScript 程序員都必須知道閉包是什么。在 JavaScript 面試中,你很可能會被問到閉包的概念。
以下是 7 個有關(guān) JavaScript 閉包的面試題,比較有挑戰(zhàn)性。
不要查看答案或運行代碼,看看自己的水平到底如何。做完這些題大約需要半小時左右。
有以下函數(shù) clickHandler
,immediate
和delayedReload
:
let countClicks = 0; button.addEventListener('click', function clickHandler() { countClicks++; }); const result = (function immediate(number) { const message = `number is: ${number}`; return message; })(100); setTimeout(function delayedReload() { location.reload(); }, 1000);
這3個函數(shù)中哪個能夠訪問外部范圍變量?
clickHandler
能夠從外部作用域訪問變量 countClicks
。
immediate
無法訪問外部作用域中的任何變量。
delayedReload
從全局作用域(也就是最外層作用域)中訪問全局變量 location
。
相關(guān)教程推薦:javascript視頻教程
下列代碼輸出什么:
(function immediateA(a) { return (function immediateB(b) { console.log(a); // => ? })(1); })(0);
輸出為:0
用參數(shù) 0
調(diào)用 immediateA
,因此 a
參數(shù)為 0
。
immediateB
函數(shù)嵌套在 immediateA
函數(shù)中,是一個閉包,它從外部 immediateA
作用域中得到 a
變量,其中 a
為 0
。因此 console.log(a)
的輸出為 0
。
下面的代碼將會輸出什么內(nèi)容?
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()
函數(shù)作用域內(nèi), count
是 0
。
但是,在條件內(nèi),另一個 let count = 1
聲明了局部變量 count
,該變量覆蓋了作用域之外的 count
。第一個 console.log(count)
輸出 1
。
第二個 console.log(count)
輸出為 0
,因為這里的 count
變量是從外部作用域訪問的。
下列代碼輸出什么:
for (var i = 0; i < 3; i++) { setTimeout(function log() { console.log(i); // => ? }, 1000); }
輸出:3
, 3
, 3
。
代碼分為兩個階段執(zhí)行。
階段1
for()
重復(fù) 3 次。在每次循環(huán)都會創(chuàng)建一個新函數(shù) log()
,該函數(shù)將捕獲變量 i
。 setTimout()
安排log()
在 1000 毫秒后執(zhí)行。
當(dāng) for()
循環(huán)完成時,變量 i
的值為 3
。
階段2
第二階段發(fā)生在 1000ms 之后:
setTimeout()
執(zhí)行預(yù)定的 log()
函數(shù)。 log()
讀取變量 i
當(dāng)前的值 3
,并輸出 3
所以輸出 3
, 3
, 3
。
下面的代碼將會輸出什么:
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()
函數(shù)被調(diào)用 3 次,將 count
增加到 3
。
message
變量存在于 createIncrement()
函數(shù)的作用域內(nèi)。其初始值為 'Count is 0'
。但即使 count
變量已經(jīng)增加了幾次,message
變量的值也始終為 'Count is 0'
。
log()
函數(shù)是一個閉包,它從 createIncrement()
作用域中獲取 message
變量。 console.log(message)
輸出錄'Count is 0'
到控制臺。
下面的函數(shù) createStack()
用于創(chuàng)建棧結(jié)構(gòu):
function createStack() { return { items: [], push(item) { this.items.push(item); }, pop() { return this.items.pop(); } }; } const stack = createStack(); stack.push(10); stack.push(5); stack.pop(); // => 5 stack.items; // => [10] stack.items = [10, 100, 1000]; // 棧結(jié)構(gòu)的封裝被破壞了
它能正常工作,但有一個小問題,因為暴露了 stack.items
屬性,所以任何人都可以直接修改 items
數(shù)組。
這是一個大問題,因為它破壞了棧的封裝:應(yīng)該只有 push()
和 pop()
方法是公開的,而 stack.items
或其他任何細(xì)節(jié)都不能被訪問。
使用閉包的概念重構(gòu)上面的棧實現(xiàn),這樣就無法在 createStack()
函數(shù)作用域之外訪問 items
數(shù)組:
function createStack() { // 把你的代碼寫在這里 } const stack = createStack(); stack.push(10); stack.push(5); stack.pop(); // => 5 stack.items; // => undefined
以下是對 createStack()
的重構(gòu):
function createStack() { const items = []; return { push(item) { items.push(item); }, pop() { return items.pop(); } }; } const stack = createStack(); stack.push(10); stack.push(5); stack.pop(); // => 5 stack.items; // => undefined
items
已被移至 createStack()
作用域內(nèi)。
這樣修改后,從 createStack()
作用域的外部無法訪問或修改 items
數(shù)組。現(xiàn)在 items
是一個私有變量,并且棧被封裝:只有 push()
和 pop()
方法是公共的。
push()
和 pop()
方法是閉包,它們從 createStack()
函數(shù)作用域中得到 items
變量。
編寫一個函數(shù) multiply()
,將兩個數(shù)字相乘:
function multiply(num1, num2) { // 把你的代碼寫在這里... }
要求:
如果用 2 個參數(shù)調(diào)用 multiply(num1,numb2)
,則應(yīng)返回這 2 個參數(shù)的乘積。
但是如果用 1個參數(shù)調(diào)用,則該函數(shù)應(yīng)返回另一個函數(shù): const anotherFunc = multiply(num1)
。返回的函數(shù)在調(diào)用 anotherFunc(num2)
時執(zhí)行乘法 num1 * num2
。
multiply(4, 5); // => 20 multiply(3, 3); // => 9 const double = multiply(2); double(5); // => 10 double(11); // => 22
以下是 multiply()
函數(shù)的一種實現(xiàn)方式:
function multiply(number1, number2) { if (number2 !== undefined) { return number1 * number2; } return function doMultiply(number2) { return number1 * number2; }; } multiply(4, 5); // => 20 multiply(3, 3); // => 9 const double = multiply(2); double(5); // => 10 double(11); // => 22
如果 number2
參數(shù)不是 undefined
,則該函數(shù)僅返回 number1 * number2
。
但是,如果 number2
是 undefined
,則意味著已經(jīng)使用一個參數(shù)調(diào)用了 multiply()
函數(shù)。這時就要返回一個函數(shù) doMultiply()
,該函數(shù)稍后被調(diào)用時將執(zhí)行實際的乘法運算。
doMultiply()
是閉包,因為它從 multiply()
作用域中得到了number1
變量。
以上是“JavaScript中關(guān)于閉包的面試題有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。