什么是声明性环境记录,它与激活对象有何不同?

时间:2013-11-22 07:07:10

标签: javascript ecmascript-5

好的,所以我最近一直在阅读ES-5词汇环境范围,我不确定我是否真的了解变量在EcmaScript中的存储方式。我做了一些研究,但没有澄清我的信息,只给我带来了两个问题。所以它们是:

  1. 第一个是关于ES-3 activations objects / variable objects。在阅读了ES-3规范和Internet上的一些资源后,我可以假设它们只是普通对象,例如像new Object创建的那些,但没有一个消息来源说“是的,这只是一个普通的对象”直。此外,Dmitry Soshnikov在他的博客上写道(重点是我的):

      

    示意性和示例,可以将变量对象呈现为普通的ECMAScript对象

    并且引用并不能让我确定激活对象到底是什么。所以这是第一个问题:激活对象是一个常规的EcmaScript对象吗?如果没有,那么它是什么呢?

  2. 在ES-5中,我们现在有object environment records,它似乎与ES-3激活对象大致相同,而declarative environment records则替换了函数中的激活对象并尝试-catch声明。因此,假设对象环境记录 只是简单的EcmaScript对象,那么什么是声明性环境记录?规范并没有澄清这一点,而且,从我在那里读到的,我无法想象这不是作为一个对象实现的。因此,如果声明性环境记录不是ES对象,那么它们是什么以及它们在代码执行期间如何实现和表示?

  3. 非常感谢您提前为我提供这个话题。

    编辑:我想我需要澄清一下这个问题是什么。我想知道的主要事情是激活对象/对象环境记录和声明性环境记录之间的确切区别。这就是我最感兴趣的。

1 个答案:

答案 0 :(得分:15)

首先,您必须意识到所有这些术语只描述了概念。他们没有规定任何形式的实施。但是因为这很难想象/可视化,所以可以帮助将这些概念视为您知道的事物的实例化,例如地图或表格。

声明性环境记录(DER)和对象环境记录(OER)有一个共同点:它们都是环境记录(ER ),将in the specification定义为:

  

环境记录记录在其关联的词汇环境范围内创建的标识符绑定。

这基本上意味着ER会跟踪变量和函数名称及其相关值。

考虑这个例子:

var foo = 42;
function bar() { };

相应的ER会有两个条目,一个用于foo,另一个用于bar。如果你想象一个ER成为一个表,那么它看起来像

  name        value
----------------------
  foo          42
  bar    <function object>

现在介绍DER和OER之间的区别。 DER可能是最容易理解的。

Declarative Environment Record

术语声明性应该听起来很熟悉,因为我们经常谈论变量声明函数声明。规范说:

  

每个声明性环境记录都与包含变量和/或函数声明的ECMAScript程序范围相关联。声明性环境记录绑定由其范围内包含的声明定义的标识符集。

所以,当你看到

var foo = 42;

function bar() {

}

然后您可以假设他们的名字和值存储在DER。

Object Environment Record

OER不太常见,但在每个JS应用程序中至少存在一个OER。规范将其描述为

  

每个对象环境记录都与称为其绑定对象的对象相关联。对象环境记录绑定直接对应于其绑定对象的属性名称的标识符名称集。

你有没有想过为什么window对象的属性是全局变量?这是因为全局范围的ER是OER:window绑定对象,并且对于其每个属性,在OER中创建相应的条目。这也在规范中:

  

全局环境的Environment Record是一个对象环境记录,其绑定对象是全局对象。

这是一个例子:让我们假设绑定对象是

var obj = {
   answer: 42
};

那么OER就是

    name        value
------------------------
    answer       42

请注意,在这种情况下,绑定对象(obj)实际上是一个JavaScript对象。当您使用with语句时,您处于相同的情况:

var obj = { foo: 42; };

with (obj) {
    foo = foo / 2;
}

console.log(obj);

with创建一个OER,并使用传递的对象中的属性名称和值填充它。这就是为什么你可以通过obj.*明确地引用它们来访问它们。如果将绑定对象分配给其中一个标识符,则OER还确保使用新值更新绑定对象。


激活对象

在ES3中看起来像激活对象(AO),它在执行函数时自动创建,并且持有对特殊arguments对象的引用。这似乎与DERs有关,但仍然是独立的 在ES5中,AO的概念似乎不再存在,我认为这是不必要的,因为arguments可以直接添加到执行上下文的DER中。

执行上下文

每当执行一个函数时,都会建立一个新的执行上下文(EC),并用于跟踪执行的状态:

  

执行上下文包含跟踪其关联代码的执行进度所需的任何状态。

这意味着引擎可以添加跟踪执行进度所需的任何信息。但规范还定义了EC 必须拥有的组件,其中一个是 VariableEnvironment ,它是一个ER(可能总是一个DER,但我不知道当然)。这意味着ER是EC的部分