当前位置:网站首页>闭包(三)----执行环境
闭包(三)----执行环境
2022-07-31 05:10:00 【F班的小夏同学】
本文我们将从执行环境的角度来了解闭包。
下面按照代码执行流的顺序对该图示进行说明:
function foo(){
var a = 2;
function bar(){
console.log(a);
}
return bar;
}
var baz = foo();
baz();
【1】代码执行流进入全局执行环境,并对全局环境中的代码进行声明提升。
【2】执行流执行第9行代码var baz=foo();调用foo()函数,此时执行流进入foo()函数执行环境中,对该执行环境中的代码进行声明提升过程。此时执行环境栈中存在两个执行环境,foo()函数为当前执行流所在执行环境。
【3】执行流执行第2行代码var a = 2;,对a进行LHS查询,给a赋值2。
【4】执行流执行第7行代码return bar;,将bar()函数作为返回值返回。按理说,这时foo()函数已经执行完毕,应该销毁其执行环境,等待垃圾回收。但因为其返回值是bar函数。bar函数中存在自由变量a,需要通过作用域链到foo()函数的执行环境中找到变量a的值,所以虽然foo函数的执行环境被销毁了,但其变量对象不能被销毁,只是从活动状态变成非活动状态;而全局执行环境的变量对象则变成活动状态;执行流继续执行第9行代码var baz = foo();,把foo()函数的返回值bar函数赋值给baz
【5】执行流执行第10行代码baz();,通过在全局执行环境中查找baz的值,baz保存着foo()函数的返回值bar。所以这时执行baz(),会调用bar()函数,此时执行流进入bar()函数执行环境中,对该执行环境中的代码进行声明提升过程。此时执行环境栈中存在三个执行环境,bar()函数为当前执行流所在执行环境。
在声明提升的过程中,由于a是个自由变量,需要通过bar()函数的作用域链bar() -> foo() -> 全局作用域进行查找,最终在foo()函数中也就是代码第2行找到var a = 2;,然后在foo()函数的执行环境中找到a的值是2,所以给a赋值2

【6】执行流执行第5行代码console.log(a);,调用内部对象console,并从console对象中log方法,将a作为参数传递进入。从bar()函数的执行环境中找到a的值是2,所以,最终在控制台显示2
【7】执行流执行第6行代码},bar()的执行环境被弹出执行环境栈,并被销毁,等待垃圾回收,控制权交还给全局执行环境
【8】当页面关闭时,所有的执行环境都被销毁
总结:
从上述说明的第5步可以看出,由于闭包bar()函数的原因,虽然foo()函数的执行环境销毁了,但其变量对象一直存在于内存中,就是为了能够使得调用bar()函数时,可以通过作用域链访问到父函数foo(),并得到其变量对象中储存的变量值。直到页面关闭,foo()函数的变量对象才会和全局的变量对象一起被销毁,从而释放内存空间
由于闭包占用内存空间,所以要谨慎使用闭包。尽量在使用完闭包后,及时解除引用,以便更早释放内存
//通过将baz置为null,解除引用
function foo(){
var a = 2;
function bar(){
console.log(a);//2
}
return bar;
}
var baz = foo();
baz();
baz = null;
/*后续代码*/
边栏推荐
- Swordsman Offer Special Assault Edition --- Day 3
- 剑指offer基础版 --- 第22天
- Element concatenation operations in numpy and pytorch: stack, concatenat, cat
- Flask-based three-party login process
- Anaconda配置环境指令
- 如何将项目部署到服务器上(全套教程)
- C语言实验二 数据类型、运算符和表达式
- 基于flask的三方登陆的流程
- 【mysql 提高查询效率】Mysql 数据库查询好慢问题解决
- Lock wait timeout exceeded解决方案
猜你喜欢

Linux系统安装mysql(rpm方式安装)

运用flask框架发送短信验证码的流程及具体代码

【LeetCode-SQL每日一练】——2. 第二高的薪水

matlab simulink欠驱动水面船舶航迹自抗扰控制研究

Unity mobile game performance optimization series: performance tuning for the CPU side

剑指offer基础版 ---- 第26天

数据库上机实验7 数据库设计

Why use Flink and how to get started with Flink?

剑指offer基础版 --- 第21天

Anaconda配置环境指令
随机推荐
Temporal介绍
C语言实验二 数据类型、运算符和表达式
剑指offer专项突击版 ---- 第2天
账号或密码多次输入错误,进行账号封禁
Paginate the list collection and display the data on the page
Lock wait timeout exceeded解决方案
剑指offer基础版 ----第31天
【一起学Rust】Rust的Hello Rust详细解析
第7章 网络层第3次练习题答案(第三版)
【LeetCode-SQL每日一练】——2. 第二高的薪水
The TOKEN value of Kubernetes joining the cluster expires
精解四大集合框架:List 核心知识总结
2022-07-30:以下go语言代码输出什么?A:[]byte{} []byte;B:[]byte{} []uint8;C:[]uint8{} []byte;D:[]uin8{} []uint8。
About the problems encountered by Xiaobai installing nodejs (npm WARN config global `--global`, `--local` are deprecated. Use `--location=glob)
MySQL (updating)
C语言实验四 循环结构程序设计(一)
torch.normal函数用法
Apache DButils使用注意事项--with modifiers “public“
面试官,不要再问我三次握手和四次挥手
tf.keras.utils.get_file()