为什么变量对象在ES5中被改为词汇环境?

时间:2016-11-11 09:20:01

标签: javascript ecmascript-5 lexical-scope ecmascript-3

ES5将variable object(VO)更改为词汇环境。这种变化的动机是什么,因为VO作为感知已经非常明显了?

2 个答案:

答案 0 :(得分:2)

我认为变量对象更类似于environment records

  

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

在ES5中,有两种不同的环境记录:

  

声明性环境记录用于定义效果   ECMAScript语言语法元素,例如 FunctionDeclarations ,    VariableDeclarations Catch 子句,它们直接将标识符绑定与ECMAScript语言值相关联。宾语   环境记录用于定义ECMAScript的效果   与程序 WithStatement 相关联的元素   标识符绑定与某个对象的属性。

所以问题是为什么引入声明性环境记录而不是像ES3变量对象那样只使用对象环境记录。不同之处在于declarative environment records可以具有不可变的绑定:

  

除了所有Environment支持的可变绑定   记录,声明性环境记录也提供了不可变的   绑定。不可变绑定是一个关联的地方   标识符和值一旦被修改就不能被修改   建立的。

不可变的绑定在对象中没有直接的等价物。属性可以定义为不可配置和不可写,变为不可变。然而,

  

创建和初始化不可变绑定是不同的步骤   这样的绑定可能存在于初始化或   未初始化的国家。

但你不能拥有未初始化的财产。如果您定义了值为undefined的不可配置的不可写属性,那么您将无法将其初始化为所需的值。

我不认为在ES5中可以使用未初始化的不可变绑定。 CreateImmutableBinding仅在Declaration Binding InstantiationFunction 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>

我认为我不能更好地表达这一点。