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.
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?
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
The following code What is output:
(function immediateA(a) { return (function immediateB(b) { console.log(a); // => ? })(1); })(0);
The output is: 0
Call with parameters 0
immediateA
, 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.
let count = 0; (function immediate() { if (count === 0) { let count = 1; console.log(count); // 输出什么? } console.log(count); // 输出什么? })();
1 and
0
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.
let count = 1 declares a local variable
count, which overrides the
count# outside the scope. ##. The first console.log(count)
outputs 1
. The second
output is 0
because the count
variable here is accessed from the outer scope.
for (var i = 0; i < 3; i++) { setTimeout(function log() { console.log(i); // => ? }, 1000); }
, 3
, 3
. The code is executed in two stages.
log()
will be created on each loop, which will capture the variable i
. setTimout()
Schedules log()
to execute after 1000 milliseconds.
When the i
is 3
.
The second phase occurs after 1000ms:
log()
function. log()
Read the current value of variable i
3
, and output 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(); // => ?
The function is called 3 times, increasing count
to 3
.
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
function is a closure that gets the message
variable from the createIncrement()
scope. console.log(message)
Output log 'Count is 0'
to the console.
is used to create the stack structure:<div class="code" style="position:relative; padding:0px; margin:0px;"><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(); // => 5
stack.items; // => [10]
stack.items = [10, 100, 1000]; // 栈结构的封装被破坏了</pre><div class="contentsignin">Copy after login</div></div>
It works fine Works, but has a small problem, since the
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
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
变量。
编写一个函数 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
变量。
如果你答对了 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!