Javascript 声明性环境记录到底是什么?它与激活对象有何不同?
好的,所以我最近一直在阅读关于ES-5词汇环境作用域的文章,我不确定我是否真的了解EcmaScript中变量的存储方式。我做了一些研究,但没有澄清我的信息,只提出了两个问题。因此,它们是:Javascript 声明性环境记录到底是什么?它与激活对象有何不同?,javascript,ecmascript-5,Javascript,Ecmascript 5,好的,所以我最近一直在阅读关于ES-5词汇环境作用域的文章,我不确定我是否真的了解EcmaScript中变量的存储方式。我做了一些研究,但没有澄清我的信息,只提出了两个问题。因此,它们是: 第一个是关于ES-3的激活对象/变量对象。在阅读了ES-3规范和互联网上的一些源代码后,我可以假设它们只是普通对象,例如由新对象创建的对象,但没有一个源代码直接说“是的,这只是一个普通对象”。此外,Dmitry Soshnikov在他的博客上写道(重点是我的): 举例来说,可以将变量对象表示为普通ECMASc
激活对象
/变量对象
。在阅读了ES-3规范和互联网上的一些源代码后,我可以假设它们只是普通对象,例如由新对象创建的对象,但没有一个源代码直接说“是的,这只是一个普通对象”。此外,Dmitry Soshnikov在他的博客上写道(重点是我的):
举例来说,可以将变量对象表示为普通ECMAScript对象
这句话并不能让我确定激活对象到底是什么。这是第一个问题:激活对象是一个普通的EcmaScript对象吗?如果不是,那又是什么呢
对象环境记录
,它们似乎或多或少与ES-3激活对象相同,还有声明性环境记录
,它们替换了函数和try catch语句中的激活对象。那么,假设对象环境记录只是普通的EcmaScript对象,那么什么是声明性环境记录?规范没有阐明这一点,而且,从我在那里读到的内容来看,我无法想象这不是作为一个对象实现的。那么,同样,如果声明性环境记录不是ES对象,那么它们是什么?它们在代码执行期间是如何实现和表示的编辑:我想我需要澄清这个问题是关于什么的。我想知道的主要事情是激活对象/对象环境记录和声明性环境记录之间的确切区别。这是我最感兴趣的。首先,你必须知道,所有这些术语都只是描述概念。它们不规定任何类型的实现。但是,由于这很难想象/可视化,因此将这些概念视为您所知道的事物(如地图或表格)的实例是非常有帮助的 声明性环境记录(DER)和对象环境记录(OER)有一个共同点:它们都是环境记录(ER),定义如下: 环境记录记录在其关联词汇环境的范围内创建的标识符绑定 这基本上意味着ER跟踪变量和函数名及其关联值 考虑这个例子:
var foo = 42;
function bar() { };
相应的ER将有两个条目,一个用于foo
,另一个用于bar
。如果你把ER想象成一张桌子,那么它看起来就像
name value
----------------------
foo 42
bar <function object>
或
然后,您可以假设它们的名称和值存储在DER中
OER不太常见,但在每个JS应用程序中至少存在一个OER。规范将其描述为
每个对象环境记录都与一个称为其绑定对象的对象相关联。对象环境记录绑定与其绑定对象的属性名称直接对应的标识符名称集
你有没有想过为什么窗口
对象的属性是全局变量?这是因为全局范围的ER是OER:窗口
是绑定对象,并且在OER中为其每个属性创建了相应的条目。这也在规范中:
全局环境的环境记录是一个对象环境记录,其绑定对象是全局对象
下面是一个示例:假设out binding对象是
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),在执行函数时自动创建激活对象,并保存对特殊
参数的引用。这似乎与DERs有关,但仍然是独立的。
在ES5中,AOs的概念似乎不再存在,我认为这是不必要的,因为参数可以直接添加到执行上下文的顺序中
执行上下文
每当执行一个函数时,就会建立一个新的执行上下文(EC),用于跟踪执行状态:
执行上下文包含跟踪其关联代码的执行进度所需的任何状态
这意味着引擎可以添加跟踪执行进度所需的任何信息。但该规范还定义了EC必须拥有的组件,其中之一是VariableEnvironment,它是一个ER(可能总是一个DER,但我不确定)。这意味着ER是EC的一部分。“它们在代码执行期间是如何实现和表示的”,这取决于引擎和引擎编写语言。规范中没有进一步指定它,因为它是一个实现细节。@FelixKling好的,所以我
name value
------------------------
answer 42
var obj = { foo: 42; };
with (obj) {
foo = foo / 2;
}
console.log(obj);