Home  >  Article  >  Web Front-end  >  7 interview questions about closures in JavaScript, can you answer them?

7 interview questions about closures in JavaScript, can you answer them?

青灯夜游
青灯夜游forward
2021-03-26 09:41:575883browse

7 interview questions about closures in JavaScript, can you answer them?

Related recommendations: 2021 Big Front-End Interview Questions Summary (Collection)

Every JavaScript programmer must Know what a closure is. In a JavaScript interview, you will most likely be asked about the concept of closures.

The following are 7 more challenging interview questions about JavaScript closures.

Don't look at the answers or run the code to see how good you are. It takes about half an hour to complete these questions.

1. Scope

has the following functions clickHandler, immediate and 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);

Which of these 3 functions can access external scope variables?

Answer

  • clickHandler Ability to access the variable countClicks from the outer scope.

  • #immediate Cannot access any variables in the outer scope.

  • delayedReload Access global variables location from the global scope (that is, the outermost scope).

Recommended related tutorials: javascript video tutorial

2. Lost parameters

The following code What is output:

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

Answer

The output is: 0

Call with parameters 0immediateA, so the a parameter is 0.

immediateB The function nested in the immediateA function is a closure that gets a# from the outer immediateA scope ## Variable, where a is 0. Therefore the output of console.log(a) is 0.

3. Who is who

What will the following code output?

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

Answer

Output

1 and 0

First statement

let count = 0 declares a variable count.

immediate() is a closure that gets the count variable from the outer scope. Within the immediate() function scope, count is 0.

However, within the condition, another

let count = 1 declares a local variable count, which overrides the count# outside the scope. ##. The first console.log(count) outputs 1. The second

console.log(count)

output is 0 because the count variable here is accessed from the outer scope.

4. Tricky Closures

What does the following code output:

for (var i = 0; i < 3; i++) {
  setTimeout(function log() {
    console.log(i); // => ?
  }, 1000);
}

Answer

Output :

3

, 3, 3. The code is executed in two stages.

Phase 1

    for()
  1. Repeat 3 times. A new function log() will be created on each loop, which will capture the variable i. setTimout() Schedules log() to execute after 1000 milliseconds. When the
  2. for()
  3. loop completes, the value of variable i is 3.
Phase 2

The second phase occurs after 1000ms:

    setTimeout()
  1. Execution Scheduled log() function. log() Read the current value of variable i3, and output 3
  2. so output
3

, 3, 3.

5. Error message

What will the following code output:

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(); // => ?

Answer

Output:

'Count is 0'

increment()

The function is called 3 times, increasing count to 3.

message

The variable exists within the scope of the createIncrement() function. Its initial value is 'Count is 0'. But even though the count variable has been incremented several times, the value of the message variable is always 'Count is 0'. The

log()

function is a closure that gets the message variable from the createIncrement() scope. console.log(message) Output log 'Count is 0' to the console.

6. Repackage

The following function

createStack()

is used to create the stack structure:<pre class="brush:php;toolbar:false">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(); // =&gt; 5 stack.items; // =&gt; [10] stack.items = [10, 100, 1000]; // 栈结构的封装被破坏了</pre>It works fine Works, but has a small problem, since the

stack.items

property is exposed, anyone can modify the items array directly. This is a big problem because it breaks the encapsulation of the stack: only the

push()

and pop() methods should be public, and Neither stack.items nor any other details can be accessed. <p>使用闭包的概念重构上面的栈实现,这样就无法在 <code>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 变量。

总结

如果你答对了 5 个以上,说明对闭包掌握的很好。如果你答对了不到 5 个,则需要好好的复习一下了。

原文地址:https://dmitripavlutin.com/simple-explanation-of-javascript-closures/

转载地址:https://segmentfault.com/a/1190000039366748

更多编程相关知识,请访问:编程视频!!

The above is the detailed content of 7 interview questions about closures in JavaScript, can you answer them?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete