当前位置:网站首页>Share 10 JS closure interview questions (diagrams), come in and see how many you can answer correctly
Share 10 JS closure interview questions (diagrams), come in and see how many you can answer correctly
2022-07-02 22:50:00 【Front end talent】
english | https://betterprogramming.pub/10-javascript-closure-challenges-explained-with-diagrams-c964110805e7
translate | Yang Xiaoai
Closure is one of the core concepts in functional programming , Is each JavaScript Necessary knowledge for developers . ad locum , I prepared 10 An interview challenge about closures , These are basically often asked in the interview .
are you ready ? We are going to start now .
Each topic has a code snippet , You need to say what the output of this code is .
1、 Range
Before saying closure , We must understand the concept of scope , It is the cornerstone of understanding closures .
What is the output of this code segment ?
var a = 10
function foo(){
console.log(a)
}
foo()
It's very simple , I believe everyone knows that the output result is 10.
By default , There is a global scope .
Local scopes are created by functions or code blocks .
When executed console.log(a) when ,JavaScript The engine will start with the function foo Created local scope lookup a. When JavaScript The engine cannot find a when , It will try in its external scope ( The global scope ) Search for a. And then it turns out a The value of is 10.
2、 Local scope
var a = 10
function foo(){
var a = 20
console.log(a)
}
a = 30
foo()
In this code , Variable a It also exists in foo Within the scope of . So when you execute console.log(a) when ,JavaScript The engine can get directly from the local scope a Value .
So the output is 20 .
remember : When JavaScript When the engine needs to query the value of a variable , It will first look in the local scope , If the variable is not found , It will continue to search in the upper range .
3、 Lexical scope
var a = 10
function foo(){
console.log(a)
}
function bar() {
var a = 20
foo()
}
bar()
This problem is easy to make mistakes , It's also a common problem in interviews , You can think about .
In short ,JavaScript It implements a method called lexical scope ( Or static scope ) Scope mechanism of . It is called morphology ( Or static ), Because the engine only looks through JavaScript Source code to determine the scope of nesting , No matter where it calls .
So the output is 10 :
4、 Modify lexical scope
If we change the code snippet to :
var a = 10
function bar() {
var a = 20
function foo(){
console.log(a)
}
foo()
}
bar()
What is the output ?
foo Range becomes bar Sub scope of scope :
When JavaScript The engine is Foo Not found in scope a when , It will start with Foo The parent scope of the scope , That is to say Bar Find in scope a, It did find a.
So the output is 20:
Okay , These are some basic challenges about scope , I believe you can pass . Now let's move on to the closure .
5、 Closure
function outerFunc() {
let a = 10;
function innerFunc() {
console.log(a);
}
return innerFunc;
}
let innerFunc = outerFunc();
innerFunc()
What is the output ? Will this code throw an exception ?
Within the scope of morphology ,innerFunc Still accessible a, Even if it is performed outside its lexical scope .
let me put it another way ,innerFunc Remember from its lexical scope ( Or turn off ) Variable a.
let me put it another way ,innerFunc It's a closure , Because it's in variables a Close within the lexical scope of .
therefore , This code will not throw an exception , It's the output 10.
6、 IIFE
(function(a) {
return (function(b) {
console.log(a);
})(1);
})(0);
This code snippet uses JavaScript Call function expression now (IIFE).
We can simply translate this code into this :
function foo(a){
function bar(b){
console.log(a)
}
return bar(1)
}
foo(0)
So the output is 0 .
A classic application of closures is to hide variables .
For example, now we need to write a counter , The basic writing is like this :
let i = 0
function increase(){
i++
console.log(`courrent counter is ${i}`)
return i
}
increase()
increase()
increase()
It can be written like this , But there will be one more variable in the global scope i, That's not good .
Now , We can use closures to hide this variable .
let increase = (function(){
let i = 0
return function(){
i++
console.log(`courrent counter is ${i}`)
return i
}
})()
increase()
increase()
increase()
such , Variable i It is hidden in the local scope , Will not pollute the overall environment .
7、 Multiple declarations and uses
let count = 0;
(function() {
if (count === 0) {
let count = 1;
console.log(count);
}
console.log(count);
})();
In this code snippet , There are two count And three count Usage of . This is a problem , You should think carefully .
First , We need to know if The code block also creates a local scope , The scope above is roughly like this .
Function Scope Did not declare its own count , So the count we use in this scope is the count of the global scope .
If Scope Declared its own count , So the count we use in this scope is the count of the current scope .
Or in this figure :
So the output is 1 , 0 :
8、 Call multiple closures
function cr
eateCounter(){
let i = 0
return function(){
i++
return i
}
}
let increase1 = createCounter()
let increase2 = createCounter()
console.log(increase1())
console.log(increase1())
console.log(increase2())
console.log(increase2())
What needs to be noted here is ,increase1 and increase2 Through different function calls createCounter Created , They don't share memory , Their i It's independent , Different .
So the output is 1 , 2 , 1 , 2 .
9、 Return function
function createCounter() {
let count = 0;
function increase() {
count++;
}
let message = `Count is ${count}`;
function log() {
console.log(message);
}
return [increase, log];
}
const [increase, log] = createCounter();
increase();
increase();
increase();
log();
This code is easy to understand , But there is a trap :message It's actually a static string , Its value is fixed to Count by 0, When we call increase perhaps log It doesn't change .
So every time I call log function , The output is always Count is 0 .
If you wish log Function checks in time count Value , Please put message move log :
function createCounter() {
let count = 0;
function increase() {
count++;
}
- let message = `Count is ${count}`;
function log() {
+ let message = `Count is ${count}`;
console.log(message);
}
return [increase, log];
}
const [increase, log] = createCounter();
increase();
increase();
increase();
log();
10、 Asynchronous closure
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 0)
}
What is the output ?
The above code is equivalent to :
var i = 0;
setTimeout(function(){
console.log(i);
},0)
i = 1;
setTimeout(function(){
console.log(i);
},0)
i = 2;
setTimeout(function(){
console.log(i);
},0)
i = 3;
setTimeout(function(){
console.log(i);
},0)
i = 4;
setTimeout(function(){
console.log(i);
},0)
i = 5
And we know JavaScript The synchronization code will be executed first , Then execute the asynchronous code . So every time you execute console.log(i) when ,i The value of has become 5.
So the output is 5 , 5 , 5 , 5 , 5 .
If we want code output 0 , 1 , 2 , 3 , 4 , How to operate ?
The solution using closures is :
for ( var i = 0 ; i < 5 ; ++i ) {
(function(cacheI){
setTimeout(function(){
console.log(cacheI);
},0)
})(i)
} ;
The above code is equivalent to :
var i = 0;
(function(cacheI){setTimeout(function(){
console.log(cacheI);
},0)})(i)
i = 1;
(function(cacheI){setTimeout(function(){
console.log(cacheI);
},0)})(i)
i = 2;
(function(cacheI){setTimeout(function(){
console.log(cacheI);
},0)})(i)
i = 3;
(function(cacheI){setTimeout(function(){
console.log(cacheI);
},0)})(i)
i = 4;
(function(cacheI){setTimeout(function(){
console.log(cacheI);
},0)})(i)
We go through JavaScript Immediately call the function expression to create the function range .i The value of is saved through closures .
congratulations , Come here , You have learned these interview challenges .
Hope in the development interview , Closure related problems won't bother you anymore .
Last , Thanks for reading , If you find it useful , Please praise me , Pay attention to me , And share it with your development friends , Maybe it can help him .
Learn more skills
Please click below official account.
边栏推荐
- DTM distributed transaction manager PHP collaboration client V0.1 beta release!!!
- 对象与对象变量
- 高并发介绍及应对
- Solve the error of changing the selected file when uploading excel file. Net:: err_ UPLOAD_ FILE_ CHANGED
- 钟薛高回应产品1小时不化:含固体成分 融化不能变成水
- 《乔布斯传》英文原著重点词汇笔记(九)【 chapter seven】
- U++ learning notes - relaxation
- Struct, bit segment, enumeration, union
- Oracle-游标
- Market Research - current market situation and future development trend of high tibial osteotomy plate
猜你喜欢
Struct, bit segment, enumeration, union
[LeetCode] 多数元素【169】
Developers share | HLS and skillfully use Axi_ Customize the master bus interface instructions and improve the data bandwidth - area exchange speed
[LeetCode] 反转字符串中的单词 III【557】
Oracle PL / SQL programming
#include errors detected. Please update your includePath.
性能优化----严苛模式
NC24325 [USACO 2012 Mar S]Flowerpot
开发者分享 | HLS, 巧用AXI_master总线接口指令的定制并提升数据带宽-面积换速度...
kubernetes 使用主机名将 pod 分配在指定节点上
随机推荐
Commodity information management system (C language document version)
[micro service sentinel] rewrite Sentinel's interface blockexceptionhandler
kubernetes 使用主机名将 pod 分配在指定节点上
杰理之修改不需要长按开机功能【篇】
NC24325 [USACO 2012 Mar S]Flowerpot
U++ learning note pile
Market Research - current market situation and future development trend of intravenous injection (IV) bottles
《乔布斯传》英文原著重点词汇笔记(十)【 chapter eight】
PHP wechat red packet grabbing algorithm
Utilisation de simpletk - 4. Question étrange
小鹏P7出事故,安全气囊未弹出,这正常吗?
[chestnut sugar GIS] ArcMap - why should the tick of classic capture be removed when using custom capture?
go 4种单例模式
世界环境日 | 周大福用心服务推动减碳环保
UE4 游戏架构 学习笔记
全面解析分享购商业模式逻辑?分享购是如何赋能企业
Jerry's modification does not require long press the boot function [chapter]
【外刊】睡眠与减肥
Graphic view frame
Struct, bit segment, enumeration, union