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