转载至:https://segmentfault.com/a/1190000010339180
VO:Variable Object的简写,就是变量对象。
AO:Activation Object的简写,叫做活动对象。
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属性,这个也可以容易理解,全局对象它不是函数。