每个执行上下文会包含三个重要属性,分别是变量对象(Variable Object,VO)、作用域链(Scope Chain)和 this 指向。
本篇主要详细介绍变量对象的生成过程。
我们已经知道,在执行上下文的创建阶段会生成变量对象,生成变量对象主要有以下三个过程:
检索当前上下文中的参数。该过程生成 arguments 对象,建立以形参变量名为属性名,形参变量值为属性值的属性;
检索当前上下文中的函数声明。该过程建立以函数名为属性名,函数所在内存地址引用为属性值的属性;
检索当前上下文中的变量声明。该过程建立以变量名为属性名,undefined 为属性值的属性(如果变量名跟已声明的形参变量名或函数名相同,则该变量声明不会干扰已经存在的这类属性)。
我们可以通过以下伪代码来表示变量对象
VO={ Arguments:{}, Param_Variable:具体值, //形参变量 Function:<function reference>, Variable:undefined },
当执行上下文进入执行阶段后,变量对象会变为活动对象(Active Object,AO)。此时原先声明的变量会被赋值。变量对象和活动对象都是指同一个对象,只是处于执行上下文的不同阶段。
我们可以通过以下伪代码来表示活动对象
AO={ Arguments:{}, Param_Variable:具体值, //形参变量 Function:<function reference>, Variable:具体值 },
举个例子~
假设有一个 javascript 文件中包含如下代码
function fn1(a) { var b = 1; function fn2() {} var c = function() {}; } fn1(0);
当 fn1 函数被调用时,fn1 执行上下文被创建(创建阶段),其变量对象如下所示
fn1Context={ VO={ Arguments:{ 0:0, length:1 }, a:0, b:undefined, fn2:<function fn2 reference>, c:undefined } }
在 fn1 函数上下文的执行阶段,变量对象变为活动对象,原先声明的变量会被赋值,其活动对象如下所示
fn1Context={ AO={ Arguments:{ 0:0, length:1 }, a:0, b:1, fn2:<function fn2 reference>, c:<function express c reference>, } }
对于全局上下文来说,由于其不会有参数传递,所以在生成变量对象的过程中只有检索当前上下文中的函数声明和检索当前上下文中的变量声明两个步骤。
在全局上下文中的变量对象(即全局对象)是我们熟悉的 window,通过该对象可以使用其预定义的变量和函数,在全局环境中所声明的变量和函数,也会成为全局对象的属性。
作者:淘淘笙悦
链接:https://www.jianshu.com/p/ff2f7332ead4