JavaScript 变量对象

执行上下文中的代码会分成两个阶段进行处理:分析、执行,我们也可以叫做:

  1. 创建执行上下文
  2. 代码执行

这篇笔记来探究一下这两个阶段中「变量对象」是如何变化的。

创建执行上下文阶段:生成变量对象

当创建执行上下文时,这时候还没有执行代码。在执行上下文中生成一个变量对象,这个变量对象会包括:

  • 函数的所有形参 (如果是函数上下文)

    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为 undefined
  • 函数声明

    • 由名称和对应值函数对象(function-object)组成一个变量对象的属性被创建(在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用)
    • 如果变量对象已经存在相同名称的属性,则完全替换这个属性
  • 变量声明

    • 由名称和对应值(undefined)组成一个变量对象的属性被创建;
    • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

🌰 举个例子

function foo(a) {
  var b = 2;
  function c() { ... }
  var d = function() { ... };
  b = 3;
}

foo(1);

在进入执行上下文后,函数 foo 的执行上下文活动对象是:

AO = {
  //通过函数的 arguments 属性初始化
  arguments: {
    0: 1,
    length: 1,
  },
  a: 1,
  b: undefined,
  c: reference to function c(){}
  d: undefined
}

代码执行

在代码执行阶段,会顺序执行代码,根据代码,修改变量对象中相对应属性的值。上面的例子,当代码执行完后,活动对象是:

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: 3,
    c: reference to function c(){},
    d: reference to FunctionExpression "d"
}

总结

  1. 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值;
  2. 在代码执行阶段,会再次修改变量对象的属性值;

参考链接