javascript中的变量对象和活动对象

变量对象

          变量对象是与执行上下文相关的数据作用域。它是一个与上下文相关的特殊对象,其中存储了在上下文中定义的变量和函数声明。
注意,函数表达式(与函数声明相对)不包含在变量对象之中。
变量对象是一个抽象概念。对于不同的上下文类型,在物理上,是使用不同的对象。比如,在全局上下文中变量对象就是全局对象本身(这就是为什么我们可以通过全局对象的属性名来关联全局变量)。

让我们在全局执行上下文中考虑下面这个例子:

var foo = 10;

function bar() {} // function declaration, FD
(function baz() {}); // function expression, FE

console.log(
  this.foo == foo, // true
  window.bar == bar // true
);

console.log(baz); // ReferenceError, "baz" is not defined

之后,全局上下文的变量对象(variable objec,简称VO)将会拥有如下属性:



再看一遍,函数baz是一个函数表达式,没有被包含在变量对象之中。这就是为什么当我们想要在函数自身之外访问它的时候会出现ReferenceError。
注意,与其他语言(比如C/C++)相比,在ECMAScript中只有函数可以创建一个新的作用域。在函数作用域中所定义的变量和内部函数在函数外边是不能直接访问到的,而且并不会污染全局变量对象。
使用eval我们也会进入一个新的(eval类型)执行上下文。无论如何,eval使用全局的变量对象或者使用caller(比如eval被调用时所在的函数)的变量对象。
那么函数和它的变量对象是怎么样的?在函数上下文中,变量对象是以活动对象(activation object)来表示的。

活动对象

当一个函数被caller所触发(被调用),一个特殊的对象,叫作活动对象(activation object)将会被创建。这个对象中包含形参和那个特殊的arguments对象(是对形参的一个映射,但是值是通过索引来获取)。活动对象之后会做为函数上下文的变量对象来使用。
换句话说,函数的变量对象也是一个同样简单的变量对象,但是除了变量和函数声明之外,它还存储了形参和arguments对象,并叫作活动对象。
考虑如下例子:
function foo(x, y) {
  var z = 30;
  function bar() {} // FD
  (function baz() {}); // FE
}

foo(10, 20);

我们看下函数foo的上下文中的活动对象(activation object,简称AO):

并且函数表达式baz还是没有被包含在变量/活动对象中。
关于这个主题所有细节方面(像变量和函数声明的提升问题(hoisting))的完整描述可以在同名的章节第二章 变量对象中找到。
注意,在ES5中变量对象和活动对象被并入了词法环境模型(lexical environments model),详细的描述可以在对应的章节找到。
然后我们向下一个部分前进。众所周知,在ECMAScript中我们可以使用内部函数,然后在这些内部函数我们可以引用父函数的变量或者全局上下文中的变量。当我们把变量对象命名为上下文的作用域对象,与上面讨论的原型链相似,这里有一个叫作作用域链的东西。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值