成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這7道關于閉包的面試題,你能答對幾個?

開發 前端
每個JavaScript程序員都必須知道閉包是什么。在JavaScript面試中,你很可能會被問到閉包的概念。以下是7個有關JavaScript閉包的面試題,比較有挑戰性。

每個 JavaScript 程序員都必須知道閉包是什么。在 JavaScript 面試中,你很可能會被問到閉包的概念。

以下是 7 個有關 JavaScript 閉包的面試題,比較有挑戰性。

不要查看答案或運行代碼,看看自己的水平到底如何。做完這些題大約需要半小時左右。

[[384154]]

1.  熱身

有以下函數 clickHandler,immediate和delayedReload:

  1. let countClicks = 0
  2. button.addEventListener('click', function clickHandler() { 
  3.   countClicks++; 
  4. }); 
  5. const result = (function immediate(number) { 
  6.   const message = `number is: ${number}`; 
  7.   return message; 
  8. })(100); 
  9. setTimeout(function delayedReload() { 
  10.   location.reload(); 
  11. }, 1000); 

這3個函數中哪個能夠訪問外部范圍變量?

答案:

  • clickHandler 能夠從外部作用域訪問變量 countClicks。
  • immediate 無法訪問外部作用域中的任何變量。
  • delayedReload 從全局作用域(也就是最外層作用域)中訪問全局變量 location。

2. 丟失的參數

下列代碼輸出什么:

  1. (function immediateA(a) { 
  2.   return (function immediateB(b) { 
  3.     console.log(a); // => ? 
  4.   })(1); 
  5. })(0); 

答案:

  • 輸出為:0
  • 用參數 0 調用 immediateA,因此 a 參數為 0。
  • immediateB 函數嵌套在 immediateA 函數中,是一個閉包,它從外部 immediateA作用域中得到 a 變量,其中 a 為 0。因此 console.log(a) 的輸出為 0。

3. 誰是誰

下面的代碼將會輸出什么內容?

  1. let count = 0
  2. (function immediate() { 
  3.   if (count === 0) { 
  4.     let count = 1
  5.     console.log(count); // 輸出什么? 
  6.   } 
  7.   console.log(count); // 輸出什么? 
  8. })(); 

答案:

  • 輸出 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 變量是從外部作用域訪問的。

4. 棘手的閉包

下列代碼輸出什么:

  1. for (var i = 0; i < 3; i++) { 
  2.   setTimeout(function log() { 
  3.     console.log(i); // => ? 
  4.   }, 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。

5. 錯誤的信息

下面的代碼將會輸出什么:

  1. function createIncrement() { 
  2.   let count = 0
  3.   function increment() {  
  4.     count++; 
  5.   } 
  6.  
  7.   let message = `Count is ${count}`; 
  8.   function log() { 
  9.     console.log(message); 
  10.   } 
  11.    
  12.   return [increment, log]; 
  13.  
  14. const [increment, log] = createIncrement(); 
  15. increment();  
  16. increment();  
  17. increment();  
  18. 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'到控制臺。

6. 重新封裝

下面的函數 createStack() 用于創建棧結構:

  1. function createStack() { 
  2.   return { 
  3.     items: [], 
  4.     push(item) { 
  5.       this.items.push(item); 
  6.     }, 
  7.     pop() { 
  8.       return this.items.pop(); 
  9.     } 
  10.   }; 
  11.  
  12. const stack = createStack(); 
  13. stack.push(10); 
  14. stack.push(5); 
  15. stack.pop(); // => 5 
  16.  
  17. stack.items; // => [10] 
  18. stack.items = [10, 100, 1000]; // 棧結構的封裝被破壞了 

它能正常工作,但有一個小問題,因為暴露了 stack.items 屬性,所以任何人都可以直接修改 items 數組。

這是一個大問題,因為它破壞了棧的封裝:應該只有 push() 和 pop() 方法是公開的,而 stack.items 或其他任何細節都不能被訪問。

使用閉包的概念重構上面的棧實現,這樣就無法在 createStack() 函數作用域之外訪問 items 數組:

  1. function createStack() { 
  2.   // 把你的代碼寫在這里 
  3.  
  4. const stack = createStack(); 
  5. stack.push(10); 
  6. stack.push(5); 
  7. stack.pop(); // => 5 
  8.  
  9. stack.items; // => undefined 

答案:

以下是對 createStack() 的重構:

  1. function createStack() { 
  2.   const items = []; 
  3.   return { 
  4.     push(item) { 
  5.       items.push(item); 
  6.     }, 
  7.     pop() { 
  8.       return items.pop(); 
  9.     } 
  10.   }; 
  11.  
  12. const stack = createStack(); 
  13. stack.push(10); 
  14. stack.push(5); 
  15. stack.pop(); // => 5 
  16.  
  17. stack.items; // => undefined 

items 已被移至 createStack() 作用域內。

這樣修改后,從 createStack() 作用域的外部無法訪問或修改 items 數組。現在 items 是一個私有變量,并且棧被封裝:只有 push() 和 pop() 方法是公共的。

push() 和 pop() 方法是閉包,它們從 createStack() 函數作用域中得到 items變量。

7. 智能乘法

編寫一個函數 multiply() ,將兩個數字相乘:

  1. function multiply(num1, num2) { 
  2.   // 把你的代碼寫在這里... 

要求:

如果用 2 個參數調用 multiply(num1,numb2),則應返回這 2 個參數的乘積。

但是如果用 1個參數調用,則該函數應返回另一個函數:const anotherFunc = multiply(num1) 。返回的函數在調用 anotherFunc(num2) 時執行乘法 num1 * num2。

  1. multiply(4, 5); // => 20 
  2. multiply(3, 3); // => 9 
  3.  
  4. const double = multiply(2); 
  5. double(5);  // => 10 
  6. double(11); // => 22 

答案:

以下是 multiply() 函數的一種實現方式:

  1. function multiply(number1, number2) { 
  2.   if (number2 !== undefined) { 
  3.     return number1 * number2; 
  4.   } 
  5.   return function doMultiply(number2) { 
  6.     return number1 * number2; 
  7.   }; 
  8.  
  9. multiply(4, 5); // => 20 
  10. multiply(3, 3); // => 9 
  11.  
  12. const double = multiply(2); 
  13. double(5);  // => 10 
  14. double(11); // => 22 

如果 number2 參數不是 undefined,則該函數僅返回 number1 * number2。

但是,如果 number2 是 undefined,則意味著已經使用一個參數調用了 multiply() 函數。這時就要返回一個函數 doMultiply(),該函數稍后被調用時將執行實際的乘法運算。

doMultiply() 是閉包,因為它從 multiply() 作用域中得到了number1 變量。

 

責任編輯:趙寧寧 來源: 前端先鋒
相關推薦

2021-03-04 09:35:54

thisJavaScript開發

2021-06-29 10:21:54

this面試前端

2018-11-09 14:00:59

Python編程語言面試題

2022-03-31 09:50:45

JS面試題

2017-11-06 13:02:37

前端setTimeout循環閉包

2021-05-08 14:20:27

Redis面試數據庫

2015-09-25 10:44:02

大數據Hadoop

2025-03-11 06:28:21

2021-03-10 08:04:11

this面試題JavaScript

2016-01-11 11:50:39

JavaScript閉包面試題

2023-02-04 18:24:10

SeataJava業務

2023-09-13 08:00:57

云原生Java開發者

2010-11-26 10:53:29

戴爾

2024-06-04 14:52:28

2022-04-08 07:52:17

CSS面試題HTML

2021-03-19 11:08:27

開發技能代碼

2020-04-26 16:55:54

MySQL數據庫

2023-09-04 08:28:34

JavaScripforEach 循環

2015-09-02 14:09:19

面試題程序設計

2021-10-28 11:40:58

回文鏈表面試題數據結構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 自拍偷拍精品 | 久久视频精品 | 国产午夜精品理论片a大结局 | 欧美一区二区三区视频 | 国产精品一区二区三区久久 | 天天躁日日躁狠狠很躁 | 国产欧美一区二区精品忘忧草 | 亚洲成人在线视频播放 | 久草影视在线 | 亚洲免费观看视频网站 | 精品国产不卡一区二区三区 | 九九久久这里只有精品 | 涩涩视频在线播放 | 国产小视频在线观看 | 中文天堂在线一区 | 国产精品久久一区二区三区 | 亚洲欧美精品 | 国产一区二区中文字幕 | 国产精品视频久久 | 亚洲国产精品99久久久久久久久 | 人操人人| 日韩在线视频一区 | 亚洲精品福利在线 | 亚洲视频在线看 | 亚洲aⅴ一区二区 | 久久久久国产精品一区 | 亚洲综合久久精品 | 神马久久久久久久久久 | 亚洲一二三区不卡 | 日韩性在线 | 久久久高清 | www.亚洲国产精品 | 成人高潮片免费视频欧美 | 国产精品久久久久久久免费观看 | 国产91亚洲精品 | 精品视频在线观看 | 欧美h | 久久久久久免费毛片精品 | 成年女人免费v片 | 亚洲视频一区在线观看 | 中文字幕一区二区三区日韩精品 |