ES5将variable object(VO)更改为词汇环境。这种变化的动机是什么,因为VO作为感知已经非常明显了?
答案 0 :(得分:2)
我认为变量对象更类似于environment records。
环境记录记录了创建的标识符绑定 在其相关的词汇环境范围内。
在ES5中,有两种不同的环境记录:
声明性环境记录用于定义效果 ECMAScript语言语法元素,例如 FunctionDeclarations , VariableDeclarations 和 Catch 子句,它们直接将标识符绑定与ECMAScript语言值相关联。宾语 环境记录用于定义ECMAScript的效果 与程序和 WithStatement 相关联的元素 标识符绑定与某个对象的属性。
所以问题是为什么引入声明性环境记录而不是像ES3变量对象那样只使用对象环境记录。不同之处在于declarative environment records可以具有不可变的绑定:
除了所有Environment支持的可变绑定 记录,声明性环境记录也提供了不可变的 绑定。不可变绑定是一个关联的地方 标识符和值一旦被修改就不能被修改 建立的。
不可变的绑定在对象中没有直接的等价物。属性可以定义为不可配置和不可写,变为不可变。然而,
创建和初始化不可变绑定是不同的步骤 这样的绑定可能存在于初始化或 未初始化的国家。
但你不能拥有未初始化的财产。如果您定义了值为undefined的不可配置的不可写属性,那么您将无法将其初始化为所需的值。
我不认为在ES5中可以使用未初始化的不可变绑定。 CreateImmutableBinding仅在Declaration Binding Instantiation和Function Definition中使用,并且在两种情况下都会立即使用InitializeImmutableBinding初始化。
但可能这样做是为了允许未初始化的不可变绑定作为语言的扩展,如JavaScript 1.5 const
。或许他们已经考虑过ES6 const
。
答案 1 :(得分:1)
您链接的ES3文章的同一作者也写了关于ES5的内容(甚至在那里链接了那个部分)。我将引用索斯尼科夫先生的"Declarative environment record" section in ECMA-262-5 in detail. Chapter 3.2. Lexical environments: ECMAScript implementation:
在一般情况下,假设声明性记录的绑定直接存储在的低级别(例如,在虚拟机的寄存器中,从而提供快速访问)。这是与ES3中使用的旧激活对象概念的主要区别。
也就是说,规范不要求(甚至间接不建议)将声明性记录实现为在这种情况下低效的简单对象。这一事实的结果是假定声明性环境记录不被直接暴露给用户级,这意味着我们无法访问这些绑定。记录的属性。实际上,我们也不可能在之前,即使在ES3中 - 激活对象也无法访问直接发送给用户(除了Rhino实现,但通过{{3属性)。
声明性记录可能允许使用完整的
__parent__
技术,即无需任何范围链查找即可直接访问所需变量 - 无论嵌套范围的深度如何(如果存储是固定且不可更改的,即使在编译时也可以知道所有变量地址)。但是,ES5规范没有直接提到这一事实。再一次,我们应该理解为什么需要用声明性环境记录替换旧的激活对象概念,这首先是 >实施效率。
因此,正如Brendan Eich lexical addressing(最后一段) - ES3中的激活对象实现只是“一个错误”:“我会注意到ES5中有一些真正的改进,特别是现在使用声明性绑定环境的第10章。 ES1-3滥用对象作为范围(同样我应该责怪1995年在JS中这样做,节省了急需实现语言所需的对象)是一个错误,而不是一个功能“。< / p>
我认为我不能更好地表达这一点。