当前位置:网站首页>闭包(三)----执行环境
闭包(三)----执行环境
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;
/*后续代码*/
边栏推荐
- pycharm专业版使用
- Redis的初识
- 实验8 DNS解析
- Interview Redis High Reliability | Master-Slave Mode, Sentinel Mode, Cluster Cluster Mode
- 面试官:生成订单30分钟未支付,则自动取消,该怎么实现?
- [Introduction to MySQL 8 to Mastery] Basics - silent installation of MySQL on Linux system, cross-version upgrade
- MySQL8--Windows下使用压缩包安装的方法
- 再见了繁琐的Excel,掌握数据分析处理技术就靠它了
- 2022-07-30:以下go语言代码输出什么?A:[]byte{} []byte;B:[]byte{} []uint8;C:[]uint8{} []byte;D:[]uin8{} []uint8。
- 【mysql 提高查询效率】Mysql 数据库查询好慢问题解决
猜你喜欢
随机推荐
C语言教程(一)-准备
Flask-based three-party login process
一文了解大厂的DDD领域驱动设计
剑指offer专项突击版 --- 第 3 天
mysql 的简单运用命令
面试官问我TCP三次握手和四次挥手,我真的是
数据库上机实验7 数据库设计
数据库上机实验4 数据更新和视图
Interviewer, don't ask me to shake hands three times and wave four times again
C语言实验三 选择结构程序设计
Mysql——字符串函数
分布式事务处理方案大 PK!
Why use Flink and how to get started with Flink?
Three handshakes and four waves
【MySQL8入门到精通】基础篇- Linux系统静默安装MySQL,跨版本升级
数据库学习笔记
numpy和pytorch中的元素拼接操作:stack,concatenat,cat
剑指offer基础版 ----- 第28天
Paginate the list collection and display the data on the page
【JS面试题】面试官:“[1,2,3].map(parseInt)“ 输出结果是什么?答上来就算你通过面试









