当前位置:网站首页>JS closure: binding of functions to their lexical environment
JS closure: binding of functions to their lexical environment
2022-07-26 09:04:00 【weixin_ thirty-nine million eight hundred and five thousand two】
Closure is JavaScript The basic concept of , Often occurs in development . that , What is a closure ? Why there are closures ?
Lexical scope
Example 1 :
function outerFunc(){
let name='kobe';
function innerFunc(){
console.log(name);
}
innerFunc();
}
outerFunc();
In the above code , stay outerFunc() A local variable is declared in name And internal functions innerFunc(),innerFunc() It is quoted in name. Execute code discovery , It can print out normally name Value .
See here , We will have a question :innerFunc() How to access name Of ?
We naturally think of : First, in the innerFunc() Internal search name Statement of , If it is not found, continue to search its external scope , In the end in outerFunc() Found the result .
This is the lexical scope : According to the location of the declared variable in the source code , To determine where variables are available ; And internal functions can access variables in their external scope
.
Closure
Example 2 :
function counterFactory(){
let count=0;
return function counter(){
console.log(count+1);
return ++count;
}
}
let counterInstance=counterFactory();
counterInstance();
This code is similar to example 1 , The difference lies in : Internal function counter() As counterFactory() The return value of , Is in counterFactory() Called after execution . Execute code discovery , It can be realized normally count Value accumulation .
See here , We will have a question : local variable count It should be counterFactory() It was released after the execution , but counterInstance() Why can I still access count Well ?
This is because JavaScript Function and its lexical environment are bound together
, That's closure . When a function is created, it holds a reference to its lexical environment , The Lexical Environment saves all local variables in the scope when the closure is created . therefore , No matter where the function is called , Can access the variables in its scope .
OOP It encapsulates
stay OOP in , Encapsulate data and methods with objects , Don't let the outside world directly access internal data , Instead, it provides public access methods
. although JavaScript No native support OOP, But we can use closures to implement encapsulation , So as to restrict the external access to data .
Example 3 :
function counterFactory(){
let count = 0;
return {
value: function(){
return count;
},
increment: function(){
return ++count;
},
decrement: function(){
return --count;
}
}
}
let counter = counterFactory();
let otherCounter = counterFactory();
console.log(`counter.value()=${
counter.value()},otherCounter.value()=${
otherCounter.value()}`);
console.log(`counter.increment()=${
counter.increment()},otherCounter.decrement()=${
otherCounter.decrement()}`);
console.log(`counter.value()=${
counter.value()},otherCounter.value()=${
otherCounter.value()}`);
In the above code ,counterFactory() A local variable is defined count, And a counter object is returned , This object contains three accesses count The public method of value()、increment()、decrement(). Execute code discovery , The three methods of the counter object can be accessed normally count, And different counter objects do not interfere with each other .
See here , We will have a question : Why do three methods of the same counter object access the same count? And many times counterFactory() Why are counter objects created independent of each other ?
First , From the above we can see that : Function creation will produce closures , And for the same counter object , The three methods are at the same time counterFactory() Created in call , So they refer to the same lexical environment , Is the same count.
However , Multiple calls counterFactory() Counter object created , It refers to different lexical environments , That is not the same count.
for Circular closure trap
Example 4 :
function closureTrap(){
var items = [0,1,2];
for(var i=0; i<items.length; ++i){
var item = items[i];
console.log(`current=${
item}`);
setTimeout(function timeoutCallback(){
console.log(`timeout=${
item}`);
},0);
}
}
closureTrap();
In the above code , In a for Set timeout callback in the loop timeoutCallback(), Print array items The elements in item. Execute this code to find , Synchronization code current It is in line with the expected results , But the timeout callback timeout It's about item All values are 2.
See here , We will have a question : Why is it printed in the callback item The value is all 2?
First ,item Yes, it is var Declarative , because Variable Promotion
,item In fact, it belongs to closureTrap() Function scoped ; then , In the loop timeoutCallback() It forms a closure , And it refers to the same lexical scope , That is all timeoutCallback() The same variable is referenced in item; When timeoutCallback() When executed ,for The cycle is over , here item The value is 2.
One way to solve this problem is similar to the example of factory function above , Create separate closures for each callback function :
function closureTrap(){
var items = [0,1,2];
for(var i=0; i<items.length; ++i){
var item = items[i];
console.log(`current=${
item}`);
setTimeout((function factory(){
var localItem = item;
return function timeoutCallback(){
console.log(`timeout=${
localItem}`);
}
})(),0);
}
}
closureTrap();
summary
Determine where variables are available according to the location of the declared variables in the source code , And the internal function can access its external scope , This is it. JavaScript The lexical scope of .
JavaScript Function is bound with its lexical scope , This is the closure . When each function instance is created , All have a quotation of their lexical environment . therefore , Whenever a function is called , Can access its scope .
With closures , The closed scope formed by it can be used to realize OOP encapsulation , So as to restrict the external access to data .
边栏推荐
- Typescript encryption tool passwordencoder
- How to quickly learn a programming language
- mysql函数
- Store a group of positive and negative numbers respectively, and count the number of 0 -- assembly language implementation
- 2022茶艺师(中级)特种作业证考试题库模拟考试平台操作
- Laravel框架日志文件存放在哪里?怎么用?
- day06 作业--技能题2
- The largest number of statistical absolute values --- assembly language
- Day06 homework - skill question 7
- Rocky基础练习题-shell脚本2
猜你喜欢
2022化工自动化控制仪表操作证考试题模拟考试平台操作
Node-v download and application, ES6 module import and export
Pan micro e-cology8 foreground SQL injection POC
Vision Group Training Day5 - machine learning, image recognition project
Pop up window in Win 11 opens with a new tab ---firefox
Day06 homework -- skill question 1
day06 作业--技能题6
Grain College of all learning source code
NFT与数字藏品到底有何区别?
【LeetCode数据库1050】合作过至少三次的演员和导演(简单题)
随机推荐
redis原理和使用-基本特性
PAT 甲级 A1013 Battle Over Cities
Espressif plays with the compilation environment
How to quickly learn a programming language
高数 | 武爷『经典系列』每日一题思路及易错点总结
分布式跟踪系统选型与实践
Study notes of automatic control principle --- stability analysis of control system
《Datawhale熊猫书》出版了!
Uni app simple mall production
Learning notes of automatic control principle - Performance Analysis of continuous time system
2022流动式起重机司机考试题模拟考试题库模拟考试平台操作
JS - DataTables 关于每页显示数的控制
ES6 modular import and export) (realize page nesting)
优秀的 Verilog/FPGA开源项目介绍(三十零)- 暴力破解MD5
围棋智能机器人阿法狗,阿尔法狗机器人围棋
聪明的美食家 C语言
NFT与数字藏品到底有何区别?
What are the differences in the performance of different usages such as count (*), count (primary key ID), count (field) and count (1)? That's more efficient
JS file import of node
Pop up window in Win 11 opens with a new tab ---firefox