当前位置:网站首页>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 .
边栏推荐
猜你喜欢

Probability model in machine learning

2022茶艺师(中级)特种作业证考试题库模拟考试平台操作

NTT(快速数论变换)多项式求逆 一千五百字解析
![[database] gbase 8A MPP cluster v95 installation and uninstall](/img/56/c0dae30ba608842c1b92e914ef42fe.png)
[database] gbase 8A MPP cluster v95 installation and uninstall

Learning notes of automatic control principle - Performance Analysis of continuous time system

The idea shortcut key ALT realizes the whole column operation

CSDN TOP1“一个处女座的程序猿“如何通过写作成为百万粉丝博主?
![[eslint] Failed to load parser ‘@typescript-eslint/parser‘ declared in ‘package. json » eslint-confi](/img/39/135d29dae23b55497728233f31aa6a.png)
[eslint] Failed to load parser ‘@typescript-eslint/parser‘ declared in ‘package. json » eslint-confi

原根与NTT 五千字详解

day06 作业--技能题6
随机推荐
PAT 甲级 A1034 Head of a Gang
day06 作业--技能题2
十大蓝筹NFT近半年数据横向对比
[recommended collection] MySQL 30000 word essence summary index (II) [easy to understand]
PAT 甲级 A1013 Battle Over Cities
谷粒学院的全部学习源码
2022茶艺师(中级)特种作业证考试题库模拟考试平台操作
2022化工自动化控制仪表操作证考试题模拟考试平台操作
The largest number of statistical absolute values --- assembly language
围棋智能机器人阿法狗,阿尔法狗机器人围棋
209. Subarray with the smallest length
PHP 之 Apple生成和验证令牌
Laravel框架日志文件存放在哪里?怎么用?
数据库操作 题目二
The Child and Binary Tree-多项式开根求逆
Center an element horizontally and vertically
idea快捷键 alt实现整列操作
node的js文件引入
Innovus卡住,提示X Error:
Pytoch realizes logistic regression