Original text: dmitripavlutin.com/javascript-… By Dmitri Pavlutin
As A JS developer, you have to know what closures are. In a front-end interview, you will most likely be asked about the concept of closures.
I’ve compiled 7 interesting and difficult questions.
Keep a pen and paper handy and try not to look at the answers or type code. I reckon you’ll need about 30 minutes.
Get started!
If you need to learn about closures, I recommend looking at the simple example of closures
directory
1. Which is the closure
2. Parameter issues
Who’s who
Tricky closures
5. Is the message true or false
6. Restore encapsulation
7. Multiply intelligently
summary
1. Which is the closure
Consider three functions: clickHandler, immediate, and delayedReload:
let countClicks = 0;
button.addEventListener('click'.function clickHandler() {
countClicks++;
});
Copy the code
const result = (function immediate(number) {
const message = `number is: ${number}`;
returnmessage; }) (100);
Copy the code
setTimeout(function delayedReload() {
location.reload();
}, 1000);
Copy the code
Question: Which of the above is a closure and why?
The answer:
The simple rule for determining whether a function is a closure is whether it can access the variables of an external function. 1. The clickHandler function is a closure because it can access external countCLicks. 2. The immediate function is not a closure because it does not access any external variables. 3. The delayedReload function is a closure because it accesses the global location variable, which is the top-level function field.Copy the code
2. Parameter issues
What does the following code print?
(function immediateA(a) {
return (function immediateB(b) {
console.log(a); // Print what}) (1); }) (0);
Copy the code
The answer:
Print a 0 because the parameter of the immediateA function is 0, so the transmission to A is 0. Then the immediateB is inside the function of the immediateA, and it is a closure, so the A in the immediateB can access the A in the external immediateA, so it prints out 0Copy the code
3: who’s who
What does the following code block print
let count = 0;
(function immediate() {
if (count === 0) {
let count = 1;
console.log(count); // What is logged?
}
console.log(count); // What is logged?}) ();Copy the code
The answer:
Print out 1 and 0 because the immediaye function was declared count= 0 at the beginning, and then the immediaye function was a closure because its count accesses the one declared at the beginning, so count was 0. Then on the conditional block, because the condition count===0 was satisfied, The first console.log(count) prints 1. The second console.log(count) prints 1 because it is in the immediate function. And count is the one that accesses the outside, the one that was declared at the beginning, so it's 0Copy the code
4: Tricky closures
What does the following code block print
for (var i = 0; i < 3; i++) {
setTimeout(function log() {
console.log(i); // What is logged?
}, 1000);
}
Copy the code
The answer:
This code block execution has two stages: stage 1:1. The for loop has three times, each time a new log function is created, and the setTimeout() in the log function is executed after 1000ms. 2. After the loop completes, I becomes 3, and setTimeout has not started yet. SetTimeou () is executed after 1000ms, because it is closed, so the inside I can access the outside I, and the outside I is now 3, so print 3, and the following setTimeou is the same. That's why you print 3,3,3.Copy the code
Challenge another question: how do I get this block of code to print 0,1,2? Leave your answers in the comments below.
5: Is the message true or false
What does the following code block print
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(); // What is logged?
Copy the code
The answer:
Increment increment increment increment increment increment increment increment increment increment increment increment increment increment However, even if count increases by one, message remains "count is 0". The log function is a closure that can access the external message, so it prints" Count is 0"Copy the code
Challenge another question: How do I get Message to display the number of counts synchronously? Leave your answers in the comments below.
6. Restore encapsulation
The createStack function creates an instance of stack:
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]; // Break the encapsulation
Copy the code
The stack looks fine, but there is a small problem that the Items property is exposed, so anyone can change it directly.
This does break stack encapsulation, as only push and POP methods should be exposed, and items should not be.
The closure concept is used to reconstruct the above createStack function so that items cannot be accessed outside of the original createStack function.
function createStack() {
// Write down your code
}
const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); / / = > 5
stack.items; // => undefined
Copy the code
The answer:
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; // => undefinedCopy the code
7. Multiply intelligently
In the multiply function, write two numbers and multiply them.
function multiply(num1, num2) {
// Write your code here...
}
Copy the code
If multiply has two arguments, it returns the result of multiplying the two arguments
If multiply has only one argument, such as const anotherFunc = multiply(num1), the anotherFunc function is returned. AnotherFunc is then assigned to a parameter num2, which returns num1 * num2
multiply(4.5); / / = > 20
multiply(3.3); / / = > 9
const double = multiply(2);
double(5); / / = > 10
double(11); / / = > 22
Copy the code
The answer:
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); / / = > 22Copy the code
summary
Compare your answers:
1, if there are 5 or more correct, it shows that you have a strong understanding ability;
2. If not, I recommend looking at the closure example
Want another challenge? Try these 7 simple but tricky JS interview questions