了解ECMAScript规范,第1部分



朋友们,美好的一天!

在本文中,我们从规范中获取一个功能并分析其解释。走。

前言


即使您非常了解JavaScript,也很难阅读规范以下代码演示了Object.prototype.hasOwnProperty的用法:

const o = {
    foo: 1
}
o.hasOwnProperty('foo') // true
o.hasOwnProperty('bar') // false

在示例中,“ o”对象没有“ hasOwnProperty”方法,因此我们引用其原型-“ Object.prototype”(原型链)。

为了描述Object.hasOwnProperty的工作方式,该规范使用以下伪代码:

Object.prototype.hasOwnProperty(V)

使用参数V调用hasOwnProperty时,将执行以下步骤: ...和HasOwnProperty(O,P) HasOwnProperty抽象操作用于确定对象是否具有自己的具有特定键的属性。返回布尔值。使用参数O和P调用该操作。此操作包括以下步骤: 什么是“抽象操作”?什么 [[ ]]?函数为什么有问号?“确认”是什么意思? 让我们找出答案。

  1. P ? ToPropertyKey(V)
  2. O ? ToObject( this)
  3. ? HasOwnProperty(O, P).







  1. (assert): Type(O) Object.
  2. : IsPropertyKey(P) true.
  3. desc ? O.[[GetOwnProperty]](P).
  4. desc undefined, false.
  5. true.





语言类型和规范中的类型


让我们从熟悉的事物开始。在规范中,有JS已知的未定义,正确和错误的值。它们都是``语言值''``语言类型的值' ',它们也由规范定义。

该规范使用内置的语言值,例如,内部数据类型可能包含值为true或false的字段。 JS引擎通常在其内部机制中不使用语言含义。例如,如果JS引擎是用C ++编写的,则很可能会使用C ++中的true和false,而不是JS中布尔值的内部表示形式。

除语言类型外,规范还使用特殊类型(规范类型)-仅在规范中使用的类型。不需要JS引擎来执行它们(但是可以)。在本文中,我们将熟悉特殊类型的“记录”(记录)及其子类型“完成记录”(完成记录)。

抽象操作


抽象操作是规范中定义的功能;定义它们是为了减少规格。不需要JS引擎将其作为独立功能执行。在JS中,不能直接调用它们。

内部插槽和内部方法


内部插槽和内部方法由[[]]中的名称指示。

内部插槽是JS对象或特殊类型的数据元素(集合)。它们用于存储有关对象状态的信息。内部方法是JS对象的成员函数。

例如,每个JS对象都有一个内部[[Prototype]]插槽和一个内部[[GetOwnProperty]]方法。

内部插槽和方法在JS中不可用。例如,我们无法访问o。[[Prototype]]或调用o。[[GetOwnProperty]]()。 JS引擎可以根据自己(内部)的需要执行它们,但是不需要这样做。

有时内部方法变成同名的抽象操作,例如[[GetOwnProperty]]:

[[GetOwnProperty]](P)

当用键“ P”调用“ O”对象的[[GetOwnProperty]]内部方法时,将执行以下操作: OrdinaryGetOwnProperty不是内部方法,因为它与任何对象都没有关联;与它一起工作的对象作为参数传递给它。 OrdinaryGetOwnProperty之所以称为“普通”,是因为它对普通对象进行操作。 ECMAScript中的对象是普通的和异常的(异国情调)。如果对象对称为基本内部方法的一组方法做出可预测的行为,则它是普通的。否则(当对象的行为不可预测;不符合预期;当对象的行为偏离正常时,是异常的),则认为这是异常的。

  1. ! OrdinaryGetOwnProperty(O, P)





最著名的异常对象是Array,因为其“ length”属性的行为不规范:设置此属性可以从数组中删除元素。

可以在此处找到基本内部方法的列表

完成记录


那问号和感叹号呢?要了解这一点,您需要了解什么是完成记录

完成记录是一种特殊类型(仅出于规范目的而定义)。JS引擎不需要具有相同的内部数据类型。

完成记录是一种具有一组固定的命名字段的数据类型。完成记录包含三个字段:
[[类型]]normal, break, continue, return throw. , normal, « () » (abrupt comlpetions)
[[Value]], , , , ,
[[Target]]( )

每个抽象操作都隐式返回完成记录。即使抽象操作的结果是一个简单的逻辑值,也将其包装在normal类型的完成记录中(请参阅隐式完成值)。

注1:这部分的规格不一致。有几个帮助程序函数返回裸值,这些裸值按原样使用,而不会从完成记录中检索出来。

注2:规范作者试图使完成记录处理更加明确。

如果算法引发异常,则这意味着将接收到具有类型([[Type]])引发和值([[Value]])作为异常对象的完成记录。我们暂时不会考虑其他类型(中断,继续和返回)。

ReturnIfAbrupt(参数)表示执行以下操作: 这是完成记录;如果突然结束,请立即返回。否则,我们从完成记录中提取值。 ReturnIfAbrupt看起来像一个函数调用,但事实并非如此。我们调用一个返回ReturnIfAbrupt()的函数,而不返回ReturnIfAbrupt本身。它的行为更像是C语言编程语言中的宏。 ReturnIfAbrupt可以使用如下: 这里进场

  1. argument - (abrupt), argument.
  2. argument argument.[[Value]].







  1. obj Foo() (obj - ).
  2. ReturnIfAbrupt(obj).
  3. Bar(obj) ( , , obj - , ).

问号:记录  ? Foo()等同于ReturnIfAbrupt(Foo())。使用此缩写有实际价值:我们不需要每次都编写错误处理程序代码。

打个比方,让val作为入口! Foo()等效于以下内容: 使用此知识,我们可以按以下方式重写Object.prototype.hasOwnProperty: Object.prototype.hasOwnProperty(P) ... HasOwnProperty可以这样重写: HasOwnProperty(O,P) 我们也可以重写内部方法[没有惊叹号的[GetOwnProperty]: O。[[GetOWnProperty]] 我们假设temp是一个新的临时变量,不会与任何东西交互。

  1. val Foo().
  2. : val .
  3. val val.[[Value]].





  1. P ToProperty(V).
  2. P , P.
  3. P P.[[Value]].
  4. O ToObject( this).
  5. O , O.
  6. O O.[[Value]].
  7. temp HasOwnProperty(O, P).
  8. temp , temp.
  9. temp temp.[[Value]].
  10. NormalCompletion(temp).





  1. : Type(O) Object.
  2. : IsPropertyKey(P) true.
  3. desc O.[[GetOWnProperty]](P).
  4. desc , desc.
  5. desc desc.[[Value]].
  6. desc undefined, NormalCompletion(false).
  7. NormalCompletion(true).





  1. temp OrdinaryGetOwnProperty(O, P).
  2. : temp .
  3. temp temp.[[Value]].
  4. NormalCompletion(temp).



我们还知道,在return语句返回除完成记录以外的内容的情况下,此内容隐式包装在NormalCompletion中。

后备:返回?富()


规范是否使用Return?Foo()-为什么在这里会有问号?

记录退货?Foo()可以扩展如下: 返回行为?Foo()对于正常终止和突然终止都是相同的。 记录退货?Foo()可让您更清楚地指示Foo返回完成记录。

  1. temp Foo().
  2. temp , temp.
  3. temp temp.[[Value]].
  4. NormalCompletion.





陈述


规范中的声明“声明”了算法的不变条件。为了清楚起见,将它们添加到规范中,但不包含任何实现要求;因此,不需要通过特定实现来验证它们。

下一步是什么?


我们学会了阅读有关Object.prototype.hasOwnProperty之类的简单方法和诸如HasOwnProperty之类的抽象操作的规范。有了这些知识,我们就可以了解其他抽象操作的作用,这将在下一部分中进行讨论。同样在下一篇文章中,我们将研究属性描述符,这是另一种特殊类型。


感谢您的关注。编码愉快!

All Articles