91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中關于閉包的面試題有哪些

發布時間:2021-03-26 10:16:08 來源:億速云 閱讀:172 作者:小新 欄目:web開發

小編給大家分享一下JavaScript中關于閉包的面試題有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!


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

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

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

1. 范圍

有以下函數 clickHandlerimmediatedelayedReload

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視頻教程

2.  丟失的參數

下列代碼輸出什么:

(function immediateA(a) {
  return (function immediateB(b) {
    console.log(a); // => ?
  })(1);
})(0);
答案

輸出為:0

用參數 0 調用 immediateA,因此 a 參數為 0

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

3. 誰是誰

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

let count = 0;
(function immediate() {
  if (count === 0) {
    let count = 1;
    console.log(count); // 輸出什么?
  }
  console.log(count); // 輸出什么?
})();
答案

輸出 10

第一個語句  let count = 0 聲明了一個變量 count

immediate() 是一個閉包,它從外部作用域得到 count 變量。在 immediate()  函數作用域內, count0

但是,在條件內,另一個 let count = 1 聲明了局部變量 count,該變量覆蓋了作用域之外的 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);
}
答案

輸出:3, 3, 3

代碼分為兩個階段執行。

階段1

  1. for() 重復 3 次。在每次循環都會創建一個新函數 log(),該函數將捕獲變量 isetTimout() 安排log() 在 1000 毫秒后執行。

  2. for() 循環完成時,變量 i 的值為 3

階段2

第二階段發生在 1000ms 之后:

  1. setTimeout() 執行預定的 log() 函數。 log() 讀取變量 i 當前的值 3,并輸出 3

所以輸出 3, 3, 3

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'到控制臺。

6. 重新封裝

下面的函數 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 變量。

7. 智能乘法

編寫一個函數  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

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

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

以上是“JavaScript中關于閉包的面試題有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永州市| 沙湾县| 聂荣县| 九台市| 凤阳县| 哈尔滨市| 鄂尔多斯市| 西城区| 鹿泉市| 彰化市| 萨嘎县| 洪湖市| 海淀区| 宁阳县| 莫力| 炎陵县| 尚义县| 曲阜市| 成武县| 滁州市| 汉中市| 奉化市| 济南市| 红河县| 油尖旺区| 延津县| 广丰县| 宜章县| 凭祥市| 武宣县| 澄迈县| 湖南省| 德安县| 于都县| 东乌珠穆沁旗| 乐业县| 永新县| 清水河县| 买车| 保康县| 阳城县|