针对函数执行上下文,为了保存这些变量,特意创建了一个对象,称它为活动对象 AO,函数内所需的变量就都保存在 AO 中,所以在函数执行上下文中,变量对象 VO 的具体表现也就是 AO。
小结:变量对象 VO 是一个抽象概念,用于保存当前执行上下文中所有的变量。所以在全局执行上下文中,因为全局对象已经保存着当前上下文所有的变量,所以 VO 在这里的具体实现就是全局对象。在函数执行上下文中,由于要保存函数形参、局部变量、自身函数对象引用变量、arguments、this,所以新创建了一个叫活动对象 AO 来保存,此时 VO 的具体实现就是 AO。
作用域链每次函数调用时,都会创建一个函数执行上下文 EC,但其中的变量对象 VO 只保存着当前上下文中的变量而已,那么函数内如果需要使用到外部函数的变量,甚至是使用全局的变量时,此时就需要依赖于执行上下文的另一个属性:作用域链。
作用域链本质上,其实是将有嵌套层次关系的执行上下文的 VO 拼接起来。
所以大部分场景作用域链只有两个节点:当前函数执行上下文的 VO –> 全局执行上下文的 VO。所以函数内才可以根据作用域链访问全局内的变量。
当出现函数内再嵌套函数时,此时作用域链就会比较长:
内层函数执行上下文的 VO –> 外层函数执行上下文的 VO –> 全局执行上下文 VO。
至于作用域链是如何将有嵌套层次的执行上下文的 VO 拼接起来,需要借助函数对象的内部属性 [[Scope]],[[]]表示执行引擎为对象创建的内部属性,我们访问不了,也操作不了。具体原理在作用域链一节中讲解。
大家好,我是 dasu,欢迎关注我的公众号(dasuAndroidTv),公众号中有我的联系方式,欢迎有事没事来唠嗑一下,如果你觉得本篇内容有帮助到你,可以转载但记得要关注,要标明原文哦,谢谢支持~