浅谈AO/VO详解
首先说明一下AO和VO的含义
- AO:Activive Object,即函数的活动对象。
- VO:Variable Object,即变量对象。
它们的作用是帮助js引擎在引用变量的时候能够去顺利找到变量。并且它们之间的联系可以实现作用域链。
VO
在执行函数的时候,会经历执行上下文的创建和代码的执行。如下图。
我们会先进行上下文的创建,创建VO、通过[Scope]
属性指向外层的VO
来进行指向外层的AO对象,那么这样就形成了作用域链。接下来是this的指向问题。
在创建VO对象的时候,会先把所有变量的声明放到一个对象属性上,但是他们的属性为空,所以这就是变量的提升。
所以简单来说。VO的作存储用就是存储变量,然后本代码或者子代码在执行的时候能够知道变量的值。并且变量定义的顺序如下:
- 参数
- 变量
- 函数
AO
AO和VO的关系:
AO可以理解为VO的一个实例,也就是VO是一个构造函数,然后VO(Context) === AO,所以VO提供的是一个函数中所有变量数据的模板。
对于同一个函数分多次执行,那么里面的变量、形参和定义的函数肯定是不同的函数,所以每次执行都会产生一个AO对象,即VO是AO的一个实例,但是这个实例并不是new 出来的,而是在同一段执行代码执行的时候放进来的。
- VO是不能访问的(除了全局上下文的VO可以间接访问),但是可以访问AO的成员(属性)。
- VO和AO其实是一个东西,只是处于不同的执行上下文生命周期。AO存在于执行上下文位于执行上下文堆栈顶部(就是上边说的’当控制进入函数代码的执行上下文时’)的时期。再粗暴点,就是函数调用时,VO被激活成了AO。
- AO通过函数的arguments属性初始化,其值是一个ArgO,包括 callee、length、arg属性。其中arg属性就相当于下标,比如第一个参数对应arg = 0。
以一个例子来说明
var a