前面的文章说到, 执行上下文的建立阶段,主要有三个内容:javascript
一、建立变量对象;二、初始化做用域链;三、肯定this的指向。java
执行上下文的执行阶段,也有三个内容:git
一、变量赋值;二、函数引用;三、执行其余代码。github
在这里先说一个前提,我提到的函数调用,说的是执行上下文的第一阶段,建立阶段(还没开始执行函数体相关的代码),提到的函数执行,说的是执行上下文的第二阶段,执行阶段(开始执行函数体相关的代码)。浏览器
其实在说到执行上下文中的的变量对象的时候,我印象中会冒出来两个英文简写:VO和AO。函数
VO:Variable Object的简写,就是变量对象。this
AO:Activation Object的简写,叫作活动对象。code
这两个东西有什么区别呢?对象
个人理解是,他们的区别就是在于执行上下文的不一样生命周期阶段,变量对象VO在执行上下文的建立阶段,而活动对象AO在执行上下文的执行阶段。生命周期
先说一下变量对象,它的结构大体如此,在函数被调用的时候被建立:
VO:{ arguments:Arguments, FunctionName:reference to function FunctionName(){}, Variables:undefined }
VO(变量对象)包含:函数的形参(arguments)、函数声明(FunctionDeclaration, FD)、变量声明(VariableDeclaration,var)三个内容。
简单来讲,举个例子:
//声明example函数 function example(x){ var a = 10; function plus(){ return a + x; } return plus(); } //调用example函数 example(5);
当调用example函数的时候,进入执行上下文的建立阶段,建立的变量对象为(本身看看什么是函数的形参、函数声明和变量声明):
VO:{ arguments:{x:undefined}, plus:reference to function plus(){}, a:undefined }
当example函数开始执行的时候,进入执行上下文的执行阶段,变量对象就会被激活,首先经过arguments属性初始化成为活动对象AO:
AO:{ arguments:{callee:example,x:5,length:1}, plus:reference to function plus(){}, a:undefined }
固然了,arguments属性的值是Arguments对象,对于VO来讲,因为建立阶段只是形参,因此VO只有x一个undefined的值,而经过传入肯定的实参5初始化后,AO中的Arguments就多了指向自身函数callee和length两个属性了。
固然,AO对象是随着执行代码的执行过程当中而变化的,随着代码的执行,变量开始初始化,下一步AO就会变成:
AO:{ arguments:{callee:example,x:5,length:1}, plus:reference to function plus(){}, a:10 }
当还有其余变量的时候,执行过程自行理解一下就好了。
因此上下文的执行阶段:变量赋值、函数引用、执行其余代码。这个过程也能够轻易理解了。
最后,想说一下全局上下文(或者叫作全局执行上下文)的VO和AO,其实你们也能够知道,其实咱们执行全部的代码,都是基于一个全局上下文上的,只要你不退出全局上下文(例如浏览器的话全局对象就是window,你不关闭窗口的话,全局上下文就不会跳出执行上下文栈),就一直都在全局执行上下文的执行阶段了,因此执行的阶段就已是AO了。其次,自己没有arguments属性,这个也能够容易理解,全局对象它不是函数。