js的闭包中关于执行环境和作用链的理解
首先讲一讲执行环境:
执行环境按照字面上来理解就是指目前代码执行所在的环境。
当JavaScript代码执行的时候,会进入不同的执行上下文,这些执行上下文会构成了一个执行上下文栈(Execution context stack,ECS)。
执行环境的分类
- 全局执行环境:
在浏览器中,其指window对象,是JS代码开始运行时的默认环境。
全局执行环境的变量对象始终都是作用域链中的最后一个对象。
- 函数执行环境:
当某个函数被调用时,会先创建一个执行环境及相应的作用域链。然后使用arguments和其他命名参数的值来初始化执行环境的变量对象。当该函数执行完之后会将该函数的执行环境弹出栈。
注:上述分类解释也表明了js中只有两种作用域,即全局作用域和函数局部作用域,不存在块作用域。
执行环境的组成
一个执行环境包括变量对象,内部[[Scope]]属性,this指针这三个属性

(注意:图片来源于简书——理解js的执行环境)
- 变量对象(Variable object,VO): 变量对象即包含变量的对象,使用包含的变量来初始化变量对象,除了我们无法访问它外,和普通对象没什么区别(全局执行环境的变量对象就是window,我们可以访问window)。
[[Scope]]属性:作用域即变量对象,作用域链是一个由变量对象组成的带头结点的单向链表,其主要作用就是用来进行变量查找。而[[Scope]]属性是一个指向这个链表头节点的指针。- this: 指向一个环境对象,注意是一个对象,而且是一个普通对象,而不是一个执行环境。
完全是小白的可能不太清楚作用域链,然后补充一下作用域链:
在前面提到过,当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对该执行环境有权访问的所有变量和函数的有序访问。
作用域链包含了执行环境栈中的每个执行环境对应的变量对象。
在访问一个变量时,先在作用域链表上的第一个变量对象上查找。如果没有找到则继续在作用域链上的第二个变量对象上查找。直至搜索到全局执行环境的变量对象即Window对象。
那么再看看闭包的特殊性访问,
function returnfunc (propertyName) {
return function (obj) { //-----这行定义并返回了一个闭包,也被称之为一个匿名函数
return obj[propertyName]; //这里用方括号法访问属性,因为属性是变量(returnfunc()函数的参数)
};
}
var savefunc = returnfunc("name"); //调用returnfunc()
var result = savefunc({name:"Picasso"});//调用savefunc()
alert(result); //返回字符串“Picasso”
作者:闭家锁
链接:https://www.zhihu.com/question/36393048/answer/71879330
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(注意:以下图片来源于知乎——理解活动对象和变量对象的区别)
以上代码的最开始的作用域链和执行环境:

我们先开始调用returnfunc()函数,马上会创建一个包含returnfunc()变量对象的行环境,作用域链开始变化,如下图:

图的白色虚线表示执行程序产生的效果,它可能表示的是返回一个结果、复制某种值、产生一个新物体、建立某种联系等。
随后returnfunc()函数会返回它内部的匿名函数,当匿名函数被返回并执行后,整个作用域链和执行环境又发生了变化:

可以看到,returnfunc函数在返回内部函数之后其执行环境就不存在了,但是其活动对象仍然在内存中,并没有被销毁;按照前面讲过的一句话“作用域链包含了执行环境栈中的每个执行环境对应的变量对象。”来看,当returnfunc的执行环境不存在之后,其所包含的活动对象是应该会被销毁。事实上,直到匿名函数被销毁,returnfunc的活动对象才会被销毁。这是闭包的特殊性,在匿名函数从returnfunc中被返回后,它的作用域链被初始化为包含returnfunc函数的活动对象和全局变量对象,即使returnfunc函数的执行环境被弹出栈,因为匿名函数的作用域链仍然在引用returnfunc函数的活动对象,returnfunc函数的活动对象仍然在内存中,这样匿名函数就可以访问returnfunc函数中定义的所有变量。
以上内容学习自:
js的闭包中关于执行环境和作用链的理解的更多相关文章
- 【JS】JavaScript中的执行环境与作用域
JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是 ...
- javascript执行环境以及作用域链的理解
在javascript脚步语言中执行环境有两种: 全局环境: 局部环境: 我们可以拿一个田径跑道来打比方,全局环境就可以理解为是最外面跑道,它包含着内部所有的东西,有人在跑步,有人在跳远,这些用着不同 ...
- js中的执行环境和作用域链
首先介绍一些即将用到的概念: 执行环境: 它定义了变量和函数有权访问其他数据的范围,每一个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个变量对象中. 所有javasc ...
- JavaScript之一: 闭包、执行环境、作用域链
这是大虾的第一篇博文,大虾试图用最直白的语言去描述出所理解的东西,大虾是菜鸟,水平有限,有误的地方希望路过的朋友们务必指正,谢谢大家了. 从读书时代一路走来,大虾在学习的时候逐渐喜欢上了去追寻根源,这 ...
- js中的执行环境及作用域
最近在面试时被问到了对作用域链的理解,感觉当时回答的不是很好,今天就来说说js中的作用域链吧. 首先来说说js中的执行环境,所谓执行环境(有时也称环境)它是JavaScript中最为重要的一个概念.执 ...
- javaScript执行环境、作用域链与闭包
一.执行环境 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为:每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象 ...
- JS执行环境,作用域链及非块状作用域
JS中的执行环境,顾名思义就是变量或函数所执行时的环境.在我的理解中,执行环境和作用域相差不大. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而在函数执行之后 ...
- javascript中函数的执行环境、作用域链、变量对象与活动对象
javascript高级程序设计中:对执行环境.作用域链.变量对象.活动对象的解释: 1.执行环境: 执行环境:有时也叫环境:是JavaScript中最为重要的一个概念:执行环境定义了变量或函数有权访 ...
- VO、AO、执行环境和作用域链
1.变量对象(variable object) 原文:Every execution context has associated with it a variable object. Variabl ...
随机推荐
- only-child选择器
:only-child选择器用于匹配属于某一个父元素的唯一子元素的元素,也就是说,如果某个父元素仅有一个子元素,则使用 :only-chlid选择器 ,可以选择这个子元素
- ACM_扫雷(dfs)
扫雷 Time Limit: 2000/1000ms (Java/Others) Problem Description: 扫雷这个游戏想必各位都是会玩的吧.简单说一下规则,n行m列的格子地图上有分布 ...
- Suricata的配置
见官网 https://suricata.readthedocs.io/en/latest/configuration/index.html# Docs » 8. Configuration Edit ...
- Sublime3注册码和安装中文包
1.Sublime3注册码 在工具栏Help中点击Enter license,粘贴下面一大串 —– BEGIN LICENSE —– Michael Barnes Single User Licens ...
- page.php 引入js文件
2种写法 <script type='text/javascript' src='<?php echo get_template_directory_uri().'/js/jquery-1 ...
- 基于Java实现的冒泡排序算法
冒泡排序是一种简单基础的排序算法,相信在大学课堂里老师已经讲过了,现在我基于Java来实现一遍. 简述 冒泡排序正如其关键词一样,杂乱的气泡经过浮动,最后大的气泡飘到了上面而小的气泡在下面,无序的元素 ...
- f# mathprovider
http://mathprovider.codeplex.com/ http://mathnetnumerics.codeplex.com/releases/view/110750 http://py ...
- configure: error: The LBL Packet Capture Library, libpcap, was not found!
configure: error: The LBL Packet Capture Library, libpcap, was not found! yum install libpcap*
- 如何理解Python中的if __name__ == '__main__'
1. 摘要 通俗的理解__name__ == '__main__':假如你叫小明.py,在朋友眼中,你是小明(__name__ == '小明'):在你自己眼中,你是你自己(__name__ == '_ ...
- Linux之用户权限管理
chmod(更改目录或文件权限) 在linux中,文件的权限分为3中,拥有者,群组,其他人.而chmod则是对权限更改的命令. u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个组,o 表示其 ...