看一下是知乎大神对于 js 执行环境 活动对象 变量对象 作用域链的解释
假设在全局环境下定义了函数pub()和变量pubvar:

var pubvar = 1;
function pub () {var pravar = 2;return pubvar + pravar;
}alert(pub(2));     //调用pub()函数

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain),这个作用域链包含了全局环境的变量对象(执行环境中定义的所有变量和函数都保存在这个对象中)并被保存在pub()函数内部的scope属性中。但是,当我们打开浏览器的时候已经存在了一个全局的执行环境,这个全局的执行环境属于浏览器,JS里浏览器被称为window对象,我们把这个环境叫做A环境,只要没有关闭浏览器,A环境会一直存在下面会提到执行环境什么时候会被创建。我们用色块表示执行环境,链条表示作用域链,作用域链上半部分是活动对象区域,下半部分是变量对象区域,如下图:

当我们调用pub()函数的时候,会在全局执行环境A中创建一个执行环境B,没错,执行环境如其名是在运行和执行代码的时候才存在的,所以我们运行浏览器的时候会创建全局的执行环境。这个时候根据pub()函数scope属性中的作用域链把pub()函数内的变量对象放入新的B环境中,作用域链也得到更新,如下图:


上图的虚线表示正在执行,全局变量对象此时处于作用域链的第二位所以标号变成了1。你可能也注意到那个arguments对象,它是在函数被创建的时候就一直存在的,无需用户创建。arguments对象保存的是函数圆括号内定义的参数,准确来说保存的是参数的值,因这里我们没有设置参数,所以显示未定义。此时我们把属于B环境的变量对象(也就是pub()函数中的所有函数和变量)叫做活动对象因此我们可以说变量对象包含了活动对象,活动对象就是作用域链上正在被执行和引用的变量对象。我们从活动对象的名称中也能看出 “执行、运行、激活” 等意味。你可以这样理解,整个代码的运行总有一个起始的对象吧,不管这个起始是变量还是函数,总要有一个称呼,虽然我们把执行环境中的变量和函数的总称叫做变量对象,但这不能反映代码的动态性,为了区别于普通的变量对象,我们创造了活动对象的概念。
我们把上面的代码变成如下:

var pubvar = 1;
function pub () {var pravar = 2;return pubvar + pravar;
}var pubvar2 = 3;
function pub2 () {var pravar = 2;return pubvar2 + pravar;
}alert(pub(2));      //调用pub()函数

这个时候全局的作用于链和执行环境如下


接着我们调用pub()函数,执行环境和作用域链如下:

你看没有被调用的pub2()函数仍然只是闲着,甚至没有被pub()函数在内部引用。由于pub2()没有参与整个pub()函数的调用过程,所以pub2()中不存在活动对象,只有“处于静止状态”的变量对象,当然也没有创建执行环境(因为它根本没执行嘛)。
到这里就完了?也没有,我们刚才也只是讨论了两个平行且毫不关联的函数其中一个被调用的状况,言下之意就是也存在函数相互影响的例子,最典型的就是闭包,闭包是一种函数嵌套的情况。定义如下代码:

function returnfunc (propertyName) {return function (obj) {             //-----这行定义并返回了一个闭包,也被称之为一个匿名函数return obj[propertyName];         //这里用方括号法访问属性,因为属性是变量(returnfunc()函数的参数)};
}var savefunc = returnfunc("name");     //调用returnfunc()
var result = savefunc({name:"Picasso"});//调用savefunc()
alert(result);                        //返回字符串“Picasso”

最开始的执行环境和作用域链


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


图的白色虚线表示执行程序产生的效果,它可能表示的是返回一个结果、复制某种值、产生一个新物体、建立某种联系等。
题外话:你会发现上图的arguments参数的值和propertyName的值是一样的,这是因为arguments保存的就是参数,采用实时映射的方式与参数建立联系,如果你在returnfunc()函数内再加一个值为{name:"picasso"},名为obj的参数,那么arguments的值变成[{name:"nicholas"},{name:picasso}],是的,你没看错,arguments是一个数组!!!
随后returnfunc()函数会返回它内部的匿名函数,当匿名函数被返回后,整个作用域链和执行环境又发生了变化:


我们看到匿名函数(闭包)被添加到了最作用域链的最前端,returnfunc()的执行环境被销毁,但我们注意到returnfunc()函数的活动对象仍然在被引用(匿名函数仍在访问propertyName参数),因此returnfunc()函数的变量对象仍然在内存中,成为活动对象。这就是为什么匿名函数就能访问returnfunc()函数定义的所有变量和全局环境定义的变量,毕竟returnfunc()的活动对象仍然保持“激活”状态。
根据上面所述,随着代码一行一行的被执行、执行环境不断被创建和销毁、变量对象间的各种关系被建立,这些背后的逻辑导致活动对象也在不断变化,这足以证明活动对象只是正在被执行和引用的变量对象。

js 执行环境 活动对象 变量对象 作用域链的理解相关推荐

  1. js执行环境作用域和闭包_JavaScript中执行上下文,提升,作用域和闭包的终极指南

    js执行环境作用域和闭包 It may seem surprising, but in my opinion the most important and fundamental concept to ...

  2. js作用域及作用域链概念理解及使用

    之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...

  3. javaScript变量、作用域链

    变量 JavaScript 变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已. 变量分为基础类型值和引用类型值: 基本类型值指的是 简单的数据段(Undefined.Null.B ...

  4. 对作用域、作用域链的理解

    全局作用域和函数作用域 (1)全局作用域 最外层函数和最外层函数外面定义的变量拥有全局作用域 所有未定义直接赋值的变量自动声明为全局作用域 所有window对象的属性拥有全局作用域 全局作用域有很大的 ...

  5. 可信执行环境TEE介绍及在区块链领域的应用

    随着移动设备的发展,移动设备的功能越来越强大,移动设备会存储用户的资产,处理支付等操作.目前移动端的系统运行环境叫做REE(Rich Execution Environment),在其中运行的系统叫做 ...

  6. 对javascript作用域链的理解

    这几天学习了一下javascript作用域链,感到这个挺重要的,所以写一篇文章分享一下: 1. 作用域链: 当代码在一个环境中执行时,会创建由变量对象构成的一个作用域链.作用域链的用途是:保证对执行环 ...

  7. 一张图展示一段js代码的一生,变量对象、作用域链、闭包、this

    我也只是进行了一个简单的囊括,图中来源均属该文,强烈推荐小伙伴去详细看一下'这波能反杀'的文章,定有收获.

  8. JS 总结之函数、作用域链

    在 JavaScript 中,函数实际上是一个对象. ? 声明 JavaScript 用 function 关键字来声明一个函数: function fn () {} 复制代码 变体:函数表达式: v ...

  9. JavaScript执行环境 + 变量对象 + 作用域链 + 闭包

    闭包真的是一个谈烂掉的内容.说到闭包,自然就涉及到执行环境.变量对象以及作用域链.汤姆大叔翻译的<深入理解JavaScript系列>很好,帮我解决了一直以来似懂非懂的很多问题,包括闭包.下 ...

最新文章

  1. datax 高级_GitHub - xhhx55/DataX
  2. 【Android】自定义环形菜单View
  3. Redis的 Window 版安装(详细配置环境,后台运行)
  4. 面向.NET开发人员的Dapr——发布和订阅
  5. Python time strftime()方法
  6. 配置svn 报错E200002解决办法
  7. CSS如何水平垂直居中?
  8. 命令行快速部署Exchange2010
  9. CAM350简单编辑gerber文件(【增加一条线】 【复制元素】 【删除元素】)
  10. 活动选择问题的贪心算法c语言,c语言背包问题_背包问题贪心算法_背包问题 贪心算法...
  11. linux 检查ntp版本,查看linux安装ntp服务器配置
  12. 计算机发展的第四阶段为中小规模集成电路,第三代中小规模集成电路计算机.ppt...
  13. 定时清理elasticsearch索引和数据
  14. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到一个处理错误
  15. [渝粤教育] 郑州轻工业大学 自动控制原理 参考 资料
  16. 在vue 中 ,dom操作滚动条 scrollTop无效
  17. 【数据结构】栈的实现与简单应用
  18. Kotlin实战案例:实现RecyclerView分页查询功能(仿照主流电商APP,可切换列表)
  19. 单阶段目标检测重要论文总结
  20. Django 表单验证之自定义表单验证器

热门文章

  1. 总裁导航V2.5.0-秒收录网站
  2. BigAnt service大蚂蚁服务端
  3. 唯美好看的动态个人鹿鸣404单页HTML源码
  4. 企业级开源电商系统5vShop商城系统源码v1.9.5
  5. Spring Cloud微服务之Nacos服务注册(九)
  6. Windows Phone 7 Developer Tools amp; Training Kit 正式版发布!
  7. C# winform 上传文件 (多种方案)
  8. sqlserver 常用存储过程集锦
  9. Linux root密码丢失后的解决
  10. 设计模式笔记[四种模式+四种原则]