【译】ECMAScript文档---序言及1-6章(下)

5.2 算法约定(Algorithm Conventions)

  规范经常使用一个带编号的列表来显示算法中的步骤。这个小算法被用做准确地表达ECMAScript语言构造须要的语义。这些算法并非打算暗示任何具体实现的使用。事实上,这里也许有更高效的算法去实现指定的特性。javascript

  算法也许被显式的参数化,在这些案例中参数的名称和用法必须做为算法定义的一部分提升。css

  算法步骤也许被细分红多个连续的子步骤。子步骤须要用缩进表示,而且也许会进一步被划分红更小的缩进的子步骤。大纲编号约定被用做标识有小写字母字符标签的一级子步骤以及有小写罗马数字标签的二级子步骤。若是超过步骤3级,那么这些规则从第四级开始用数字标签进行重复。例如:html

1.Top-level step
    a.Substep.
    b.Substep.
        i.Subsubstep.
            1.Subsubsubstep
                a.Subsubsubsubstep
                    i.Subsubsubsubsubstep

  一个步骤或者子步骤也许会使用“if”去断言它的子步骤的条件。在这样的案例中,这些子步骤只能适用于“if”断言为true的状况。若是一个步骤或者子步骤以单词“else”开始,那么表示这是以前的“if”断言的同一级的否认断言。java

  一个步骤也许会指定它的子步骤的迭代程序。node

  一个以“Assert:”开头的步骤断言一个它的算法里不变的条件。这样的断言被用做使算法不变量显式地展现,不然它将是隐式的。这样的断言不增长额外的语义需求,所以在实现中不须要被检查。它们被使用只是为了使算法更清晰。git

  对于任意形如“Let x be someValue”的值,算法步骤也许会声明命名别名。这些别名便可能经过x也可能经过someValue引用,它们指向同一个潜在的数据,而且修改其中任意一个对另外一个都是可见的。那些想避免这样的相似引用的算法步骤须要显式地复制一份右值:即“Let x be a copy of someValue”建立了一个someValue的浅复制。程序员

  一旦声明完毕,别名也许会在随后的任意步骤或者子步骤中被引用,可是它们也许不会在最高级步骤中被引用。别名也许会经过形如“Set x to someOtherValue”这样的形式被修改。github

5.2.1 抽象操做(Abstract Operations)

  为了促进它们在本规范的多个地方使用,一些算法,咱们称之为抽象操做,在参数化的函数形式中中命名和书写,以便它们可以在其它算法中经过名称来引用。抽象操做一般是被经过一个功能化的应用风格引用,如OperationName(arg1, arg2)。一些抽象操做被看成像类规范里抽象的多态发送同样。这样的相似类的方法抽象操做一般经过一个方法应用风格被引用,如someValue.OperationName(arg1, arg2)。正则表达式

5.2.2 特定语法操做(Syntax-Directed Operations)

  一个特定的语法操做是一个具备名称的操做,它的定义包含了一系列算法,每一个算法与一个或者多个ECMAScript文法的产生式相关联。一个有多个可选定义的产生式一般对于每一个可选部分都有一个独立的算法。当一个算法与一个文法产生式相关联的时候,它也许会引用这个产生式可选部分的终结符或者非终结符,就好像它们是这个算法的参数同样。当出现这种状况时,非终结符指向实际的源代码中与之匹配的可选部分的定义。算法

  当一个算法与一个产生式的可选部分关联的时候,这个可选部分一般不会带上“[ ]” 文法注释。这样的注释只应该影响可选部分的语法识别,不该该对相关的可选部分的语义有影响。
Syntax-directed operations are invoked with a parse node and, optionally, other parameters by using the conventions on steps 1, 3, and 4 in the following algorithm:
  特定语法操做同一个解析节点一块儿被调用,还能够在步骤1,3,4中使用这个约定的其它参数。

1. Let `status` be the result of performing SyntaxDirectedOperation of SomeNonTerminal.

2. Let `someParseNode` be the parse of some source text.

3. Perform SyntaxDirectedOperation of `someParseNode`.

4. Perform SyntaxDirectedOperation of `someParseNode` passing
"value" as the argument.

  除非显式地指定,不然,全部相关联的产生式对于每一个也许会被应用到这个产生式左值的非终结符的操做都有一个隐式的定义。若是存在的话,这个隐式的定义简单地再次对一样的参数运用这个相同的定义,对于这些相关联的产生式惟一的右值非终结符,随后返回处理结果。例如,假设一些算法有以下形式的步骤:“返回被解析的块的结果(Return the result of evaluating Block)”,而且这里有一个产生式:
  

Block :
    { StatementList }

  可是解析操做并无关联这个产生式的算法。那么在这样的案例中,解析操做隐式地包含了下面形式的关联:
运行时语义: 解析(Runtime Semantics: Evaluation)

Block : { StatementList }

  1. Return the result of evaluating StatementList.

5.2.3 运行时语义(Runtime Semantics)

  必须在运行时被调用的指定语义的算法就叫运行时语义。运行时语义经过抽象操做或者指定语法操做来定义。这样的算法必须返回一个完成记录。

5.2.3.1 隐式完成值(Implicit Completion Values)

<h5 align="center">表8:完成记录字段(Completion Record Fields)</h5>

  完成类型是一个记录,用于解释某些执行非外部控制转移语句(例如break, continue, return, throw)运行时值和控制流的传播。

  完成类型的值是记录值,它们的字段定义在表8中。这样的值被称为完成记录。

Filed Value 含义
[[Type]] normal, break, continue, return, throw其中的一个 完成值的类型
[[Value]] 一个ECMAScript语言值或者空值 产生的值
[[Target]] 任意ECMAScript字符串或者空值 指定的控制转移的目标标签/元素

  本规范的算法经常隐式地返回一个[[Type]]值为normal的完成记录(见表8,译注:因为不少解释位于较后的章节,如这个定义就位于第6章,并且比较重要,全部对于某些这样的状况会把它提到前面来)。除非它是上下文中另外很是明显的部分,一个返回一个值的算法语句,那么这个值将不是一个完成值。例如:
1. Return "Infinity".
  与下面的是同一个含义:
1. Return NormalCompletion("Infinity").

  然而,若是一个“return”语句的值表达式是一个完成记录构造的字面量,那么完成记录的结果将被返回。若是这个值表达式是一个对抽象操做的调用,那么“return”语句简单地返回这个抽象操做产生的完成记录。

  抽象操做完成(完成记录)被用做强调以前计算的完成记录被返回。完成(Completion)这个抽象操做接收一个参数,即完成记录(completionRecord),而后执行下面的步骤:

1. Assert: completionRecord is a Completion Record.
2. Return completionRecord as the Completion Record of this abstract operation.

  一个在算法步骤中没有值的“return”语句与下面的是一样的意思:
1. Return NormalCompletion(undefined).

  对于任意的在一个上下文中没有显示地须要一个完整的完成记录值的引用,等价于一个显式地对完成记录的[[Value]]字段的引用,除非完成记录是一个打断/中断(abrupt)完成。

5.2.3.2 抛出一个异常(Throw an Exception)

  描述抛出一个异常的算法步骤,例如:
1. Throw a TypeError exception.

  意思就是:
1. Return Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}.

5.2.3.3 若是被打断则返回(ReturnIfAbrupt)

  算法步骤说明或者等同于:
1. ReturnIfAbrupt(argument).

  意思就是(译注:abrupt completion就是上面提到的改变控制流如break之类的语句,除了这些以外的就是普通的Completion Record):

1. If argument is an abrupt completion, return argument.
2. Else if argument is a Completion Record, let argument be argument.[[Value]].

  算法步骤说明或者等同于:
1. ReturnIfAbrupt(AbstractOperation()).

  意思就是:

1. Let hygienicTemp be AbstractOperation().
2. If hygienicTemp is an abrupt completion, return hygienicTemp.
3. Else if hygienicTemp is a Completion Record, let hygienicTemp be hygienicTemp.[[Value]].

  这里的hygienicTemp是短暂的(临时的),而且只在ReturnIfAbrupt有关的步骤中中可见。

  算法步骤说明或者等同于:
1. Let result be AbstractOperation(ReturnIfAbrupt(argument)).

  意思就是:

1. If argument is an abrupt completion, return argument.
2. If argument is a Completion Record, let argument be argument.[[Value]].
3. Let result be AbstractOperation(argument).

5.2.3.4 若是被打断则返回 缩写(ReturnIfAbrupt Shorthands)

  对抽象操做和以?为前缀的指定语法操做的调用暗示着ReturnIfAbrupt须要被应用到结果的完成记录中。例如,步骤:
1. ? OperationName().

  等价于下面的步骤:
1. ReturnIfAbrupt(OperationName()).

  类似的,对于程序方法的风格,步骤:
1. ? someValue.OperationName().

  等价于
1. ReturnIfAbrupt(someValue.OperationName()).

  类似的,前缀!被用做暗示下列的对于抽象或者指定语法操做的调用将不会返回一个打断的(abrupt)完成值,而且做为结果的完成记录的[[Value]]字段应该被用做替换操做的返回值,例如,步骤:
1. Let val be ! OperationName().

  等价于下面的步骤:

1. Let val be OperationName().
2. Assert: val is never an abrupt completion.
3. If val is a Completion Record, set val to val.[[Value]].

  对于运行时语义的指定语法的操做经过在调用操做前替换!或者?来利用这个缩写。
1. Perform ! SyntaxDirectedOperation of NonTerminal.

5.2.4 静态语义(Static Semantics)

  上下文无关文法不能足够好的去表达全部定义的规则,无论是一个输入元素的流造成的一个合法的将被解析的ECMAScript脚本(Script)仍是模块(Module)。在一些状况中,须要额外的规则经过使用ECMAScript算法约定或者散文要求(prose requirements)来展现。这样的规则老是与一个文法的产生式相关联,被称做产生式的静态语义。

  静态语义规则拥有名称,而且一般用一个算法来定义。具备名称的静态语义规则与文法产生式相关联,对于每一个可采用的具备名称的静态语义规则,一个包含多个可选部分定义的产生式一般会对每一个可选部分定义一个独有的算法。

  除非在本规范中其它指定的文法产生式可选部分隐式地包含一个叫作Contains的接收一个值为包含相关产生式的文法的终结符或者非终结符的symbol参数静态语义规则的定义。默认的包含定义为:

1. For each child node child of this Parse Node, do
    a. If child is an instance of symbol, return true.
    b. If child is an instance of a nonterminal, then
        i. Let contained be the result of child Contains symbol.
        ii. If contained is true, return true.
2. Return false.

  上面的定义是显式地重写了规范的产生式。

  一个特殊的静态语义规则是早期(提早)错误规则(Early Error Rule)。早期错误规则定了早期错误条件(参见条款16),它们与具体的文法产生式相关联。大多数早期错误规则的解析不是在本规范的算法中显式地被调用。一个符合规范的实现必须在第一次解析脚本或者模块以前,验证全部被用做解析脚本或者模块的产生式的早期错误规则。若是违反了任意的早期错误规则,那么脚本或者模块就是不合法的,而且不能被解析执行。

5.2.5 数学操做(Mathematical Operations)

  除非其它地方特别注明不包括无限而且不包括负0(为了与正0区分),数学操做,例如加,减,否认(逻辑非),乘,除以及随后在条款中定义的数学函数应老是被看成是对于数学中全部真实数字计算出来的准确的结果。本规范算法中的浮点运算包含显式地的步骤,它们对于处理无穷,有符号的0,以及舍入是必要的。若是一个数学操做或者函数被应用在一个浮点数上,那么它必须被看成应用到用浮点数表示的具体的数学值;这样的浮点数必须是有限的,而且若是它是+0或者-0的话,那么相应的数学值就是简简单单的0。

  数学函数abx(x)用来计算x的绝对值,若是x是负数(小于0),那么结果就是-x,不然结果就是x自己。

  数学函数min(x1, x2, ..., xN)计算从xxN的最小值。数学函数max(x1, x2, ..., xN)计算从xxN的最大值。这些数学函数的域(译注:即定义域和值域)以及范围包括+∞和-∞。

  符号“x modulo y”(译注:即x模y)(y必须是有限的且是非0的)计算出一个值k,它的符号与y一致(或者是0),这样的k知足abs(k) < abs(y),以及能找到某个整数y,使得x-k = q * y
The mathematical function floor(x) produces the largest integer (closest to positive infinity) that is not larger than x.
  

注意 floor(x) = x-(x modulo 1). (译注:即模运算是向0方向舍入)

6 ECMAScript数据类型和值(ECMAScript Data Types and Values)

  本规范的算法操做的值每个都有其相应的类型。最可能的值类型偏偏是那些定义在这个条款中的类型。类型又进一步分为ECMAScript语言类型(language types)以及规范类型(specification types)。

  在本规范总,符号“Type(x)”用来做为“the type of x”的简写,这里的“type”指向定义在本条款中的ECMAScript语言以及规范类型。当术语“empty”被使用时,就好像它正在命名一个值,这和说“no value of any type”是相等的(译注:即任何类型都没有这个值)。

6.1 ECMAScript语言类型(ECMAScript Language Types)

  一个ECMAScript语言类型对应那些被使用ECMAScript语言的ECMAScript程序员直接操做的值。ECMAScript语言类型是Undefined, Null, Boolean, String, Symbol, Number, and Object。一个ECMAScript语言值是一个具备ECMAScript语言类型特征的值。

6.1.1 Undefined类型(The Undefined Type)

  Undefined类型仅仅只有一个值,被称为undefined。任何没有被分配一个值的变量的值就是undefined

6.1.2 Null类型(The Null Type)

  Null类型仅仅只有一个值,被称为null

6.1.3 Boolean类型(The Boolean Type)

  Boolean类型表明一个拥有两个值的逻辑的实体,它们被称为truefalse

6.1.4 String类型(The String Type)

  String类型是全部0或者16bit无符号整数值(“elements”)的有顺序的序列的集合,最大的长度是2^53 - 1个元素的长度。String类型一般被用做在一个正在运行的ECMAScript程序上展现文本数据,在这样的案例中,String中的每一个元素都被看成一个UTF-16码元(code unit)。每一个元素都被看成这个序列中的一个占位。这些位置使用非负整数来进行索引。第一个元素(若是存在的话)在索引(index)0的位置,下一个元素(若是存在的话)在索引1的位置,以此类推。一个字符串的长度是它内部的元素(即16-bit值)的个数。空字符串的长度为0,所以没有元素。

  ECMAScript操做解释String值的地方,每一个元素被解释成单个的UTF-16码元。然而,ECMAScript不会对这个字符串的码元序列施加任何的限制或者需求,因此当按照UTF-16码元解释的时候,它们也许是不合规范的。不解释字符串内容的操做把它们看成没有任何差异的16-bit无符号整数。函数String.prototype.normalize能够被用来显式地规范化一个字符串值。函数String.prototype.localeCompare内部对字符串进行了规范化,可是除此以外的其它操做都没有隐式地规范化字符串。只有那些被显式地指定用来处理语言或者对语言环境敏感的操做才会产生语言敏感的结果。

注意 这个设计背后的基本原理是保证Strings的实现尽量是简单和高效的。若是ECMAScript源文本在规范化的形式C内,那么字符串字面量也应当被认为是规范化的,只要它们不包含任何Unicode转移序列。

  一些操做把字符串内容解释为UTF-16编码的Unicode码元。在这样的案例中,解释的过程是:

  • 一个范围在0到0xD7FF的码元或者范围在0xE000到0xFFFF的码元被解释成一个相同值的码点(code point)。
  • 一个两个码元的序列,第一个码元c1在范围0XD800到0XDBFF,第二个码元c2在范围0xDC00到0xDFFF,这样的称为代理对,它们被解释为一个值为(c1 - 0xD800) * 0x400 + (c2 - 0xDC00) + 0x10000的码点(See 10.1.2)。
  • 一个范围在0xD800到0xDFFF可是不属于代理对的码元,被解释为一个相同值的码点。

译注,若是对于Unicode不是很了解的话,推荐阅读每一个JavaScript开发者都该懂的Unicode

6.1.5 Symbol类型(The Symbol Type)

  Symbol类型是全部非字符串的也许被用做做为对象的属性的值的集合。

  每一个可能的Symbol值都是惟一的和不可变的。

  每一个Symbol值永远地保持一个与之关联的叫作[[Description]]的值,它要么是undefined要么是一个字符串值。

6.1.5.1 著名的Symbol(Well-Known Symbols)

  著名的symbols就是咱们说的那些被本规范的算法显式地引用的内置Symbol值。它们一般被用做属性(propertied)的key,这些key的值为规范的算法提供了一种扩展。除非其它地方显式地说明,著名的symbol的值被全部(realm)共享。

  在本规范内,一个著名的symbol经过形如@@name的形式被引用,这里的name是表1中的某一个:
<h6 align="center" >表 1 著名的Symbol</h6>

Specification Name [[Description]] Value and Purpose
@@hasInstance "Symbol.hasInstance" 一个方法,决定一个构造函数对象是否能将一个对象识别为它的实例。由instance操做的语义来调用。
@@isConcatSpreadable "Symbol.isConcatSpreadable" 一个Boolean值,若是为true,表明一个对象对于Array.prototype.concat应该被压成扁平的再加入进去。(译注:好比a.concat一个元素,若是这个元素为数组,会把这个数组的元素挨个pusha后面,这个时候这个元素的@@isConcatSpreadable就为true,若是这个元素是一个对象,那么就把这个对象当成一个总体pusha后面,这个时候这个元素的@@isConcatSpreadable就为false
@@iterator "Symbol.iterator" 一个方法,返回一个对象默认的迭代器(iterator)。由for-of操做的语义来调用。
@@match "Symbol.match" 一个正则表达式方法,匹配正则表达式对应的字符串。由 String.prototype.match调用。
@@replace "Symbol.replace" 一个正则表达式方法,替换匹配到的字符串中的子串。由String.prototype.replace调用。
@@search "Symbol.search" 一个正则表达式方法,返回一个字符串中匹配这个正则表达式的位置的索引。由String.prototype.search调用。
@@species "Symbol.species" 这是一个函数类型的属性,那些被用来建立派生对象的构造函数就拥有这个属性。
@@split "Symbol.split" 一个正则表达式方法,在指定的匹配这个正则表达式的地方分割这个字符串。
@@toPrimitive "Symbol.toPrimitive" 一个方法,将一个对象转换为对应的原始值(primitive value)。由ToPrimitive方法调用。
@@toStringTag "Symbol.toStringTag" 这是一个String类型的属性,被用在一个对象在建立时默认的字符串描述上。经过内置的Object.prototype.toString方法访问。
@@unscopables *"Symbol.unscopables"* 这是一个Object类型的属性,它自身以及继承来的属性的名称是在with环境中对应的对象中被排除了的属性的名称。(译注:即with的对象里有的属性,这个@@unscopables的对象里属性不该该包含这些属性。)

6.1.6 Number类型(The Number Type)

  Number类型恰好有18437736874454810627个(即$2^{64}$ - $2^{53}$ + 3)值,表示双精度64位格式的在IEEE标准中关于二进制浮点类型运算的IEEE 754-2008规范的值,除了9007199254740990 (即$2^{53}$ - 2)是一个IEEE规范中大相径庭的“Not-a-Number”值(译注:可参考规范中的2.1.35,6.2节等等),被做为一个单独的NaN值在ECMAScript中展现。(注意NaN由程序表达式NaN产生。)

注意:在一个Number值已经被存储后,位模式(bit pattern)也许能够经过一个ArrayBuffer或者SharedArrayBuffer观察到,可是这和Number值的内部表示同样,不是ECMAScript的实现所必须的。

  这里有两种其它的特殊值,叫作正无穷和负无穷。为了简洁和说明目的,这些值也分别用符号+∞-∞表示。(注意这两个无穷数由程序表达式+Infinity(或者简单的Infinity)和-Infinity产生)

  其它的18437736874454810624个值(即,$2^{64}$ - $2^{53}$)被称做有限数(finite numbers)。其中一半是正数,一半是负数;对于每一个有限正数值,这里都有一个相应量级的负数值。

  注意这里既有正0也有负0。为了简洁和说明的目的,这些值也分别用符号+0-0表示。(注意这两个不一样的零数字值由程序表达式+0(或者简单的0)和-0产生。)

  18437736874454810622(即$2^{64}$ - $2^{53}$ - 2)个有限非0值有下面两种类型:

18428729675200069632 (that is, 264-254) of them are normalized, having the form
  其中的18428729675200069632(即$2^{64}$ - $2^{54}$)个值是被范式化/规范化(normalized)了的,它们是下面的形式:

$s × m × 2^e$

  这里的s是+1或者-1,m是一个小于$2^{53}$可是不小于$2^{52}$的正数,e是一个正数,范围从-1074到971,先后都包含。

  剩下的9007199254740990(即$2^{53} - 2$)个值是没有被范式化的,它们是下面的形式:

$s × m × 2^e$

  这里的s是+1或者-1,m是一个小于$2^{52}$的正数,e是-1074。

  注意Number类型能表示的全部的正数和负数它们的量级/指数都不超过$2^{53}$。(事实上,整数0有两种表示,+0-0

  若是是非0的话,一个有限数有一个奇数的尾数那么它就是奇数,整数m用来表示这个尾数(即上面提到的两种形式之一)。不然,它就有一个偶数的尾数。

  在本规范中,短语“the Number value for x”里的x恰好表明一个非0值的真实的数学量(也有多是如π之类的无理数),也意味着一个Number值按照下面的方式被选择出来。首先考虑Number类型中全部的有限数的集合,除去-0,加上两个Number类型没法表示的值,被称为$2^{1024}$(即1 × $2^{53}$ $2^{1024}$)以及$-2^{1024}$(即-1 × $2^{53}$ $2^{1024}$)。而后选择这个集合中离x最近的元素。若是有两个值同样接近,那么选择有偶数尾数的那一个。处于为此目的考虑,两个额外的值$2^{1024}$和$-2^{1024}$被认为是拥有相同的偶数尾数。最后,若是选择的是$2^{1024}$,用+∞替换它。若是选择的是$-2^{1024}$,用-∞替换它。若是选择的是+0,只在x小于0时才用-0替换它。除了上面提到的这些,任意其它的选择值是不会发生变化的。最后的结果就是x的Number值。(这样就能恰好产生与IEEE 754-2008的“round to nearest, ties to even”行为模式相对应的值。)

  一些ECMAScript操做符仅仅处理指定范围的整数,例如先后都包含的$-2^{31}$到$2^{31} - 1$。或者是0到$2^{16} - 1$的范围。这些操做符接收任意Number类型的值,可是首先会将它们转换成像上面提到的这些范围内的值。能够参考7.1节的数字转换操做。

6.1.7 Object类型(The Object Type)

  一个对象逻辑上是一个属性的集合。每一个属性要么是一个数据属性(data property),要么是一个访问器属性(accessor property):

  • 一个数据属性关联一个ECMAScript语言值的key值以及一个Boolean属性的集合。
  • 一个访问器属性关联一个或两个访问器函数的key值,一级一个Boolean属性的集合。访问器函数被用来存储或者检索与这个属性相关的ECMAScript语言值

  属性是用key值来识别的。一个属性的key值要么是一个ECMAScript String值,要么是一个Symbol值。全部的String和Symbol值,包括空字符串,都是合法的属性key值。当一个属性的key是String值的时候,这个属性的name是这个属性的key。

  一个整数索引是一个字符串值的属性key,它是一个规范的数字String(canonical numeric String)(参考7.1.16)。它的数字值要么是+0,要么是一个小于等于$2^{53}$-1的正数。一个数组索引是一个整数索引,它的数字值i的范围是+0 ≤ i < $2^{32}-1$。(译注:即Array(2**32)会报错:Uncaught RangeError: Invalid array length,而Array(2**32 - 1)不会

  属性的key被用来访问属性以及它们的值。这里有两种对属性的访问:get和set。分别对应值的检索和赋值。经过get和set来进行属性访问既包括直接属于本身的属性,也包括经过属性继承关系从其它相关对象继承来的属性。继承的属性也多是另外一个对象的自身属性或者继承来的属性。一个对象的每一个自身属性必须有一个key值来区分它和这个对象的其它的自身属性。

  全部的对象都是逻辑上的属性集合,可是对象却有多种形式用来区分访问以及变化它们的属性的语义。普通的对象是对象的最多见形式,拥有默认的对象语义。一个外来对象是这样的对象形式,它的属性语义与默认语义的各个方面都有区别。

6.1.7.1 Property Attributes

  本规范中的属性(Attributes)被用做定义和解释对象属性(Object properties)的状态。一个数据属性(data property)与表2中列出的属性的key值相关联。

<h6 align="center">表2 Attributes of a Data Property</h6>

Attribute Name Value Domain Description
[[Value]] 任意的ECMAScript语言类型 访问属性时被检索到的值
[[Writable]] Boolean 若是为false,任未尝试经过[[Set]]去改变这个属性的[[Value]]属性的ECMAScript代码都不会成功。
[[Enumerable]] Boolean 若是为true,这个属性被for-in枚举时将会是可枚举的(参考13.7.5)。不然,这个属性就是不可枚举的。
[[Configurable]] Boolean 若是为false,任未尝试删除这个属性,把这个属性改成访问器属性,或者改变它的除了[[Value]]以外的属性,或者改变它的[[Writable]]为false的操做都会失败。

  一个访问器属性accessor property)与表3中列出的属性的key值相关联。

<h6 align="center">表3 Attributes of an Accessor Property</h6>

Attribute Name Value Domain Description
[[Get]] Object\ Undefined 若是这个值是一个对象,那么它必须是一个函数对象。在每次访问这个属性的时候,这个函数的内置[[Call]]方法(下面的表6中)将会被调用,同时会向这个方法传入一个空的arguments。
[[Set]] Object\ Undefined 若是这个值是一个对象,那么它必须是一个函数对象。在每次设置这个属性的时候,这个函数的内置[[Call]]方法(下面的表6中)将会被调用,同时会向这个方法传入包含所赋的值的arguments,做为这个arguments的惟一参数。[[Set]]内置方法也许会对后续的[[Get]]内置方法调用产生的返回值产生影响,但不是必须的。
[[Enumerable]] Boolean 若是为true,这个属性被for-in枚举时将会是可枚举的(参考13.7.5)。不然,这个属性就是不可枚举的。
[[Configurable]] Boolean 若是为false,任未尝试删除这个属性,把这个属性改成数据属性,或者改变它的其它attributes的操做都会失败。

  若是一个属性的attributes的初始值没有被本规范显式地指定的时候,那么使用在表4中定义的默认值:
<h6 align="center">表4 Default Attribute Values</h6>

Attribute Name Default Value
[[Value]] undefined
[[Get]] undefined
[[Set]] undefined
[[Writable]] false
[[Enumerable]] false
[[Configurable]] false

6.1.7.2 对象的内置方法和内置槽(Object Internal Methods and Internal Slots)

  在ECMAScript中,对象的实际语义是经过算法来调用内置方法指定的。在ECMAScript引擎中的每一个对象都与一系列的定义它的运行时行为的内置方法相关联。这些内置方法不属于ECMAScript语言的一部分。经过本规范定义它们的部分仅仅是为了解释和说明的目的。然而,在ECMAScript具体实现中的每一个对象必须表现得像这些内置方法与它关联了同样。其中的准确的行为由实现来决定。

  内置方法(Internal method)的名称是多种多样的。这意味着当一个常见的内置方法被调用的时候,不一样的对象值也许会运行不一样的算法。内置方法被调用时实际的对象成为这个调用的“目标”(“target”)。若是在运行时一个算法的实现尝试去使用一个对象不支持的内置方法,一个TypeError将会被抛出。

  内置槽(Internal slots)对应相关联对象的内部状态,被ECMAScript规范中不一样的算法使用。内置槽不是对象的属性,也不会被继承。根据规范中具体的内置槽,这样的内部状态也许包含任意ECMAScript语言类型的值或者指定的ECMAScript规范类型的值。除非显式地指定,不然内置槽做为建立一个对象的一部分过程被分配,而且也许不能被动态地添加到对象上。除非显式地指定,不然一个内置槽的初始值是undefined。本规范内不一样的算法都会建立有内置槽的对象。然而,ECMAScript语言不提供直接的方法去访问一个对象的内置槽。

  本规范内的内置方法和内置槽使用闭合的双方括号[[]]来标识。

  下方的表5总结了被规范使用的适用于全部对象的建立或者被ECMAScript代码操做的相当重要的内置方法。每一个对象对于全部相当重要的算法都必须有相应的算法。然而,全部的对象没有必要对那些方法使用相同的算法。

  下面的表5中的 “Signature”列以及其它类似的表格描述了每一个内置方法的调用模式。调用模式老是包含一个括起来的描述参数名的列表。若是一个参数名与ECMAScript类型的名字同样,那么表明描述的是参数值须要的类型。若是一个内置方法显式地返回了一个值,它的参数列表随后就会跟着一个“→”符合,以及返回值的类型。在signature中使用的类型的名字指向在条款6中定义的类型,另外还增长了一些下面的名称。“any”表明这个值也许是任意的ECMAScript语言值。一个内置方法会隐式地返回一个完成记录。除了它的参数,一个内置方法还老是会访问这个方法调用的对象的目标(即前面提到的target)。

<h6 align="center">表5 Essential Internal Methods</h6>

Internal Method Signature Description
[[GetPrototypeOf]] ( ) → Object Null 肯定为这个对象提供继承的属性的对象。一个null值表明没有继承的属性。
[[SetPrototypeOf]] (Object Null) → Boolean 将这个对象与提供继承的属性的对象相关联。传递null表示没有继承的属性。返回true表示操做成功,返回false表示操做失败。
[[IsExtensible]] ( ) → Boolean 决定是否容许添加额外的属性到这个对象上。
[[PreventExtensions]] ( ) → Boolean 控制一个新的属性是否能加到这个对象上。返回true表示操做成功,返回false表示操做失败。
[[GetOwnProperty]] (propertyKey) → Undefined \ Property Descriptor 返回这个对象的一个自身属性(own property)的属性描述符,它的key为propertyKey,或者undefined(若是没有这样的属性存在的话)。
[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) → Boolean 建立或者改变自身属性,它的key为propertyKey,它的状态为PropertyDescriptor。返回true表示属性被成功建立/更新,返回false表示属性不能被建立/更新。
[[HasProperty]] (propertyKey) → Boolean 返回一个Boolean值,表明这个对象是否已经有一个自身的或者继承的key为propertyKey的属性。
[[Get]] (propertyKey, Receiver) → any 返回这个对象里key值为propertyKey的属性的值。若是任何的ECMAScript代码必须被运行来检索这个属性值,Receiver就会做为解析代码时的this值。
[[Set]] (propertyKey, value, Receiver) → Boolean 设置这个对象中的key为propertyKey的属性的值为value。若是任何的ECMAScript代码必须被运行来检索这个属性值,Receiver就会做为解析代码时的this值。返回true表示这个属性能被设置,返回false表示不能被设置。
[[Delete]] (propertyKey) → Boolean 移除这个对象的key值为propertyKey的自身属性。返回false表示这个属性没有被移除,仍然存在。返回true表示已经被移除,再也不存在。
[[OwnPropertyKeys]] ( ) → List of propertyKey 返回一个一个List,这个List里的元素都来自这个对象的自身属性的key。

  下方的表6总结了也许会被看成函数来调用的对象的额外的相当重要的内置方法。一个函数对象是一个支持[[Call]]内置方法的对象。一个构造器(也被称为构造函数)是一个支持[[Construct]]内置方法的函数对象。
<h6 align="center">表6 Additional Essential Internal Methods of Function Objects</h6>

Internal Method Signature Description
[[Call]] (any, a List of any) → any \ Null 执行这个对象相关联的代码。经过一个函数表达式来调用。经过调用表达式,传递给内置方法的arguments是一个this值以及一个包含传递给本身函数的参数的列表。实现这个内置方法的对象被称为可调用的(callable)。
[[Construct]] (a List of any, Object) → Object \ Null 经过new或者super操做符建立一个对象。传递给这个内置方法的第一个参数是一个包含操做符的参数的列表。第二个参数是new操做符初始化时应用的对象。实现这个内置方法的对象被称为构造函数(constructors)。一个函数对象不必定是构造函数,这样的非构造函数的函数对象没有[[Construct]]内置方法。(译注:好比new Window()会抛出Uncaught TypeError: Illegal constructor)

  这些普通对象的相当重要的内置方法的语义和标准的外来对象在条款9中指出。若是一个外来对象的任何内置方法的使用不被实现所支持,那么尝试使用这个用法时必须抛出一个TypeError异常。

6.1.7.3 相当重要的内置方法的不变量(Invariants of the Essential Internal Methods)

  ECMAScript引擎中的对象的内置方法必须符合下方指定的不变量列表。普通的ECMAScript对象以及本规范中标准的外来对象维护这些不变量。ECMAScript代理(Proxy)对象经过对[[ProxyHandler]]对象被调用的结果的运行时检查来维护这些不变量。

  任何提供外来对象的实现也必须维护这些对象的不变量。违反这些不变量也许会形成ECMAScript代码出现不可预测的行为以及发生安全问题。然而,一个实现对于违反不变量的行为在内存安全问题上绝对不能妥协。

  一个实现必须不容许这些不变量在任何例如提供实现了相当重要的内置方法的功能可是没有执行它们的不变量的可选接口的行为中被规避。

定义:

  • 一个内置方法的target是一个对象,这个对象的对应的内置方法会被调用。
  • 若是一个target被观察到它的[[IsExtensible]]内置方法返回false或者[[PreventExtensions]]返回true,那么它是不可扩展的。
  • 一个不存在的属性是指那些在不可扩展的target的自身属性上不存在的属性。
  • 全部引用SameValue(译注:即判断两个值是否相等)的地方都根据SameValue算法。

[[GetPrototypeOf]] ( )

  • 返回值的类型必须是Object或者Null。
  • 若是target是不可扩展的,而且[[GetPrototypeOf]]返回了一个值v,那么任何未来的对[[GetPrototypeOf]]的调用都应该返回v的SameValue。

注意1: 一个对象的原型链的长度应该是有限的(也就是说,从任意对象开始,递归地对结果应用[[GetPrototypeOf]]内置方法最终应该获得null)。然而,若是这个原型链包含任意的不使用普通对象的[[GetPrototypeOf]]定义的外来对象,那么做为一个对象的不变量水平,这个要求不是强制的。当访问对象属性的时候,这样的一个环形的原型链也许最终会致使无限循环。

[[SetPrototypeOf]] (V)

  • 返回值的类型必须是Boolean。
  • 若是target是不可扩展的,[[SetPrototypeOf]]必须返回false,除非V是target观察到的[[GetPrototypeOf]]值的SameValue。

[[IsExtensible]] ( )

  • 返回值的类型必须是Boolean。
  • 若是[[IsExtensible]]返回false,全部未来的在target上的对[[IsExtensible]]的调用都必须返回false。

[[PreventExtensions]] ( )

  • 返回值的类型必须是Boolean。
  • 若是[[PreventExtensions]]返回false,全部未来的在target上的对[[IsExtensible]]的调用都必须返回false,而且如今开始target被认为是不可扩展的。

[[GetOwnProperty]] ( )

  • 返回值的类型必须是Property Descriptor或者Undefined。
  • If the Type of the return value is Property Descriptor, the return value must be a complete property descriptor (see 6.2.5.6).
  • 若是返回值的类型是Property Descriptor,那么返回值必须是一个完整的property descriptor(参考6.2.5.6)。
  • 若是一个属性P被描述为一个含有Desc的数据属性。访问器 的[[Value]]等于v,访问器的[[Writable]]以及[[Configurable]]为false,那么对于访问器的[[Value]]属性,必须返回SameValue。未来对这个属性的[[Value]]属性的调用变成[[GetOwnProperty]] ( P )。
  • 若是P的除了[[Writable]]以外的属性随着时间发生了变化或者这个属性消失了,那么P的[[Configurable]]属性必须变成true。
  • 若是[[Writable]]属性从false变成了true,那么[[Configurable]]属性必须变成true。
  • 若是target是不可扩展的,而且P是不存在的,那么全部未来在target上对[[GetOwnProperty]] (P)的调用必须把P描述为不存在的(即[[GetOwnProperty]] (P)必须返回undefined)。

注意2: 做为第三个不变量的结论,若是一个属性被描述为一个数据属性而且随着时间它返回不一样的值,那么访问器的[[Writable]]和[[Configurable]]属性必须是true,即便没有机制去改变经过其它内置方法暴露出来的值。

[[DefineOwnProperty]] ( P, Desc)

  • 返回值的类型必须是Boolean。
  • 若是P以前已经被观察为target的一个不可配置的自身属性,[[DefineOwnProperty]]必须返回false,除非:
    1. P是一个不可配置的可写的自身数据属性。一个不可配置的可写数据属性能被改变为一个不可配置的不可写的数据属性。
    1. 全部在访问器中的属性都是P的属性的SameValue。
  • 若是target是不可扩展的而且P是一个不存在的自身属性,[[DefineOwnProperty]] (P, Desc)必须返回false。也就是说,一个不可扩展的对象不能扩展新的属性。

[[HasProperty]] ( P )

  • 返回值的类型必须是Boolean。
  • 若是P以前被观察到是target的一个不可配置的数据或者访问器自身属性,[[HasProperty]]必须返回true。

[[Get]] (P, Receiver)

  • 若是P以前被观察到是target的一个value为v的不可配置且不可写的自身数据属性,那么[[Get]]必须返回SameValue。
  • 若是P以前被观察到是[[Get]]属性是undefined的target的一个不可配置的自身访问器属性,那么[[Get]]操做必须返回undefined。

[[Set]] ( P, V, Receiver)

  • 返回值的类型必须是Boolean。
  • 若是P以前被观察到是target的一个value为v的不可配置且不可写的自身数据属性,那么[[Set]]必须返回false,除非V是P的[[Value]]属性的SameValue。
  • 若是P以前被观察到[[Set]]属性是undefined 的target的是一个不可配置的自身访问器属性,那么[[Set]]操做必须返回undefined。

[[Delete]] ( P )

  • 返回值的类型必须是Boolean。
  • 若是P以前被观察到是target的一个不可配置的自身数据属性或者访问器属性,[[Delete]]必须返回false。

[[OwnPropertyKeys]] ( )

  • 返回值必须是一个List。
  • 返回的List中的每一个元素的类型要么是String,要么是Symbol。
  • 返回的List必须至少包含以前观察到的全部的不可配置的自身属性。
  • 若是这个对象是不可扩展的,那么返回的List必须只能包含这个对象的全部经过[[GetOwnProperty]]观察到的自身属性的key。

[[Construct]] ( )

  • 返回值的类型必须是Object。

6.1.7.4 著名的内部对象(Well-Known Intrinsic Objects)

  著名的内部函数是那些被本规范的算法显式地引用的内置对象,在这些函数中一般拥有基于特定域(realm-specific)下的特性。除非另有说明,不然每一个内部对象在每一个中都实际对应一个类似对象的集合。

  在本规范中,一个像%name%这样的引用就表示关联到当前域的内部对象的对应的name。当前域的肯定以及它的内部状况在8.3节中描述。著名/常见的内部对象在下面的表7中列出。
<h6 align="center">表7 Well-known Intrinsic Objects</h6>

Intrinsic Name Global Name ECMAScript Language Association
%Array% Array Array构造函数(参考22.1.1
%ArrayBuffer% ArrayBuffer ArrayBuffer构造函数(参考24.1.2
%ArrayBufferPrototype% ArrayBuffer.prototype %ArrayBuffer%的prototype数据属性的初始值
%ArrayIteratorPrototype% Array迭代器的prototype对象(参考22.1.5
%ArrayPrototype% Array.prototype %Array%的prototype数据属性的初始值(参考22.1.3
%ArrayProto_values% Array.prototype.values %ArrayPrototype%的prototype数据属性的初始值(参考22.1.3.30
%AsyncFunction% 异步的函数对象(async function )的构造器(参考25.5.1
%AsyncFunctionPrototype% %AsyncFunction%的prototype数据属性的初始值
%Atomics% Atomics Atomic对象(参考24.4
%Boolean% Boolean Boolean构造函数(参考19.3.1
%BooleanPrototype% Boolean.prototype %Boolean%的prototype数据属性的初始值(参考19.3.3
%DataView% DataView DataView构造函数(参考24.3.2
%DataViewPrototype% DataView.prototype %DataView%的prototype数据属性的初始值
%Date% Date Date构造函数(参考20.3.2
%DatePrototype% Date.prototype %Date%的prototype数据属性的初始值
%decodeURI% decodeURI decodeURI函数(参考18.2.6.2
%decodeURIComponent% decodeURIComponent decodeURIComponent函数(参考18.2.6.3
%encodeURI% encodeURI encodeURI函数(参考18.2.6.4
%encodeURIComponent% encodeURIComponent encodeURIComponent函数(参考18.2.6.5
%Error% Error Error构造函数(参考19.5.1
%ErrorPrototype% Error.prototype %DataView%的prototype数据属性的初始值
%eval% eval eval函数(参考18.2.1
%EvalError% EvalError EvalError构造函数(参考19.5.5.1
%EvalErrorPrototype% EvalError.prototype %EvalError%的prototype数据属性的初始值
%Float32Array% Float32Array Float32Array构造函数(参考22.2
%Float32ArrayPrototype% Float32Array.prototype %Float32Array%的prototype数据属性的初始值
%Float64Array% Float64Array Float64Array构造函数(参考22.2
%Float64ArrayPrototype% Float64Array.prototype %Float64Array%的prototype数据属性的初始值
%Function% Function Function构造函数(参考19.2.1
%FunctionPrototype% Function.prototype %Function%的prototype数据属性的初始值
%Generator% %Generator%的prototype数据属性的初始值
%GeneratorFunction% generator对象的构造函数(参考25.2.1
%GeneratorPrototype% %Generator%的prototype数据属性的初始值
%Int8Array% Int8Array Int8Array构造函数(参考22.2
%Int8ArrayPrototype% Int8Array.prototype %Int8Array%的prototype数据属性的初始值
%Int16Array% Int16Array Int16Array构造函数(参考22.2
%Int16ArrayPrototype% Int16Array.prototype %Int16Array%的prototype数据属性的初始值
%Int32Array% Int32Array Int32Array构造函数(参考22.2
%Int32ArrayPrototype% Int32Array.prototype %Int32Array%的prototype数据属性的初始值
%isFinite% isFinite isFinite函数(参考18.2.2
%isNaN% isNaN isNaN函数(参考18.2.3
%IteratorPrototype% 一个对象,全部的内置对象的迭代器对象间接地都从这个对象继承而来。
%JSON% JSON JSON对象(参考24.5
%Map% Map Map构造函数(参考23.1.1
%MapIteratorPrototype% Map迭代器对象的原型(参考23.1.5
%MapPrototype% Map.prototype %Map%的prototype数据属性的初始值
%Math% Math JSON对象(参考20.2
%Number% Number Number构造函数(参考20.1.1
%NumberPrototype% Number.prototype %Number%的prototype数据属性的初始值
%Object% Object Object构造函数(参考19.1.1
%ObjectPrototype% Object.prototype %Object%的prototype数据属性的初始值(参考19.1.3
%ObjProto_toString% Object.prototype.toString %Object%的toString数据属性的初始值(参考19.1.3.6
%ObjProto_valueOf% Object.prototype.valueOf %Object%的valueOf数据属性的初始值(参考19.1.3.7
%parseFloat% parseFloat parseFloat函数(参考18.2.4
%parseInt% parseInt parseInt函数(参考18.2.5
%Promise% Promise Promise构造函数(参考25.4.3
%PromisePrototype% Promise.prototype %Promise%的prototype数据属性的初始值
%Proxy% Proxy Proxy构造函数(参考26.2.1
%RangeError% RangeError RangeError构造函数(参考19.5.2.2
%RangeErrorPrototype% RangeError.prototype %RangeError%的prototype数据属性的初始值
%ReferenceError% ReferenceError ReferenceError构造函数(参考19.5.5.3
%ReferenceErrorPrototype% ReferenceError.prototype %ReferenceError%的prototype数据属性的初始值
%Reflect% Reflect Reflect对象(参考26.1
%RegExp% RegExp RegExp构造函数(参考21.2.3
%RegExpPrototype% RegExp.prototype %RegExp%的prototype数据属性的初始值
%Set% Set Set构造函数(参考23.2.1
%SetIteratorPrototype% Set迭代器对象的prototype(参考23.2.5
%SetPrototype% Set.prototype %Set%的prototype数据属性的初始值
%SharedArrayBuffer% SharedArrayBuffer SharedArrayBuffer构造函数(参考24.2.2
%SharedArrayBufferPrototype% SharedArrayBuffer.prototype %SharedArrayBuffer%的prototype数据属性的初始值
%String% String String构造函数(参考21.1.1
%StringIteratorPrototype% String迭代器对象的prototype(参考21.1.5
%StringPrototype% String.prototype %String%的prototype数据属性的初始值
%Symbol% Symbol Symbol构造函数(参考19.4.1
%SymbolPrototype% Symbol.prototype %Symbol%的prototype数据属性的初始值(参考19.4.3
%SyntaxError% SyntaxError SyntaxError构造函数(参考19.5.5.4
%SyntaxErrorPrototype% SyntaxError.prototype %SyntaxError%的prototype数据属性的初始值
%ThrowTypeError% 一个函数对象,无条件的抛出一个%TypeError%的实例
%TypedArray% 全部的typed Array构造函数的父类(参考22.2.1
%TypedArrayPrototype% %TypedArray%的prototype数据属性的初始值
%TypeError% TypeError TypeError构造函数(参考19.5.5.5
%TypeErrorPrototype% TypeError.prototype %TypeError%的prototype数据属性的初始值
%Uint8Array% Uint8Array Uint8Array构造函数(参考22.2
%Uint8ArrayPrototype% Uint8Array.prototype %Uint8Array%的prototype数据属性的初始值
%Uint8ClampedArray% Uint8ClampedArray Uint8ClampedArray构造函数(参考22.2
%Uint8ClampedArrayPrototype% Uint8ClampedArray.prototype %Uint8ClampedArray%的prototype数据属性的初始值
%Uint16Array% Uint16Array Uint16Array构造函数(参考22.2
%Uint16ArrayPrototype% Uint16Array.prototype %Uint16Array%的prototype数据属性的初始值
%Uint32Array% Uint32Array Uint32Array构造函数(参考22.2
%Uint32ArrayPrototype% Uint32Array.prototype %Uint32Array%的prototype数据属性的初始值
%URIError% URIError URIError构造函数(参考19.5.5.6
%URIErrorPrototype% URIError.prototype %URIError%的prototype数据属性的初始值
%WeakMap% WeakMap WeakMap构造函数(参考23.3.1
%WeakMapPrototype% WeakMap.prototype %WeakMap%的prototype数据属性的初始值
%WeakSet% WeakSet WeakSet构造函数(参考23.4.1
%WeakSetPrototype% WeakSet.prototype %WeakSet%的prototype数据属性的初始值

6.2 ECMAScript规范类型(ECMAScript Specification Types)

译注:本小节大部分都是算法,因此只是翻译一下各小节最前面的文字介绍,即每一小节的后面还有不少相应的算法,对这些具体算法有兴趣能够本身再研究研究。

  一个规范类型对应那些被用在算法中去描述ECMAScript语言结构/构造以及ECMAScript语言类型的元数据。规范类型包括,Reference, List, Completion, Property Descriptor, Lexical Environment, Environment Record以及Data Block。规范类型的值是规范里才有的,在ECMAScript实现中没有必要与任何具体的实体相关联/对应。规范类型的值也许被用来描述ECMAScript表达式解析后的中间结果,可是这样的值不能被存储做为ECMAScript语言变量的对象属性或值的一部分。

6.2.1 List和Record规范类型(The List and Record Specification Types)

  List类型被用来解释在new表达式中对于argument lists(参考12.3.6)的解析,以及在函数调用中,或者在其它须要一个简单的有序的值的list的算法的地方。List类型的值是简单的包含各自list元素的有序序列。这些序列多是任意的长度。一个list中的元素能够经过0到某个区间内的索引来随机访问。为了记数方便,一个类数组语法能够被用来访问List的元素。例如,arguments[2]是arguments List中第三个元素的简写。

  为了本规范的记法方便,能够用一个字面量语法来表示一个新的List值。例如,« 1, 2 »定义了一个有2个元素的List值,每一个元素都被实例化为了一个具体的值。一个新的空的List能够用« »表示。

  Record类型被用来描述在本规范算法内的数据的聚合。一个Record类型的值包含一个或者多个命名的字段。每一个字段的值要么是一个ECMAScript值,要么是一个用一个关联Record类型的名称表示的抽象值。字段名老是双方括号闭合的,例如[[Value]]。

  为了本规范的方便,一个相似对象字面量的语法被用来表示一个Record值。例如,{[[Field1]]: 42, [[Field2]]: false, [[Field3]]: empty}定义了一个包含3个字段的Record值,其中的每个都被实例化为了一个具体的值。字段名的顺序是不重要的。任何没有被显式地列出的字段都被认为是不存在的。

  在规范的文本和算法中,点符号也许会被用来指向一个具体的一个Record值的某个特定字段。例如,若是R是一个在以前的段落中出现的record,那么R.[[Field2]]表明“R中名称叫[[Field2]]的字段”的简写。

  常见的使用Record字段组合模式的地方也许是被命名了的,这个名称用在一个Record字面量前做为前缀,来定义描述的具体的聚合类型。例如: PropertyDescriptor{[[Value]]: 42, [[Writable]]: false, [[Configurable]]: true}。

6.2.2 Set和关系规范类型(The Set and Relation Specification Types)

  Set类型被用来解释在内存模型中无序元素的集合。Set类型的值是简单的元素的集合,其中没有任何元素出现超过2次。元素能够从Set中添加或者删除。不一样的Set能够是联合的(unioned),分割的或者除去的。(译注:即数学中集合之间的关系,并,交,补等。)

  关系(Realation)类型被用来解释在Set上的约束。一个关系类型的值是它的的值域中有序对的集合。例如,一个在event上的关系是一个有序的的event对的集合。对于一个关系R以及在R的值域中的两个值aba R b是有序对(a, b)R的成员的简写。(译注,这些在离散数学中应该都有相应的介绍)

6.2.3 完成记录规范类型(The Completion Record Specification Type)

  见前面的5.2.3.1。

6.2.4 引用规范类型(The Reference Specification Type)

注意:引用类型被用来解释像deletetypeof,赋值等操做符以及super关键字,以及其它语言特性的行为。例如,赋值操做左边的操做数应该是一个引用。

  一个引用是一个解析后的名称或者属性绑定。一个引用包含3个组件,基础的值组件(value component),引用的名称组件(name component),以及Boolean值的是否引用严格模式的flag。基础的值组件要么是undefined,要么是一个对象,Boolean,String,Symbol,Number,或者一个环境记录(Environment Record)。一个undefined的基础值组件表示这个引用不能被解析为一个绑定。引用的名称组件是一个String或者Symbol值。

  一个超引用(Super Reference)是一个被用来表示一个用super关键字表示的名称绑定的引用。一个超引用有额外的thisValue组件,它的基础值组件将永远不能是一个环境记录。

6.2.5 属性描述符规范类型(The Property Descriptor Specification Type)

  属性描述符类型被用来解释对对象属性的操做和物化。属性描述符的值是Record。每一个字段的名称是一个属性名称,而且它的值是一个在6.1.7.1中相对应的属性值。此外,任何的字段均可以被展现或者省略。在本规范内使用的对属性描述符的record的标签字面量描述模式名称为“PropertyDescriptor”。

  属性描述符的值也许会进一步在基于已存在的某些字段上依据数据属性描述符和访问器属性描述符来进行分类。一个数据属性描述符是包含[[Value]]或者[[Writable]]的任意字段名的类型。一个访问器属性描述符包含是[[Get]]或者[[Set]]的任意字段名的类型。任何一个属性描述符都包含[[Enumerable]]和[[Configurable]]字段名。一个属性描述符的值也许既不是一个数据属性描述符,也不是一个访问器属性描述符。然而,也有可能都是。一个通常的属性描述符是一个既不是数据属性描述符也不是访问器属性描述符的值。一个彻底被填充的属性描述符是一个包含全部在表2或者表3中相应属性的字段的访问器属性描述符或者一个数据属性描述符。

6.2.6 词法环境和环境记录规范类型(The Lexical Environment and Environment Record Specification Types)

The Lexical Environment and Environment Record types are used to explain the behaviour of name resolution in nested functions and blocks. These types and the operations upon them are defined in 8.1.
  词法环境(Lexical Environment)和环境记录(Environment Record)类型被用来解释在嵌套的函数和块中的名称解析行为。在这些之上的类型和操做定义在8.1中。

6.2.7 Data Blocks

  数据块规范类型被用来描述一个独特的且不可变的基于字节(8bit)数字值序列。一个数据块值用一个固定的字节数字来建立,它们的每个的初始值都为0。

  为了本规范的方便,一个类数组语法被用来访问一个数据块值的本身的字节。这个符号用一个从0开始的索引的字节序列整数来表示一个数据块值。例如,若是db是一个5个字节的数据块值,那么db[2]就能被用来访问它的第三个字节。

  一个驻留在内存中的数据块能被多个代理并发地引用,咱们特指这样的叫作共享数据块。一个共享数据块有一个没有地址的(address-free)标识(出于为了平等地测试共享数据块的值的目的):它并非挂在任意进程中这个块对应的虚拟地址上,而是内存中的这个表明这个块的地址。只有当它们包含的地址的集合是相等的,两个数据块才是相等的。不然,它们就是不相等的,它们包含的地址的集合的交叉为空。最后,共享数据块与数据块是有区别的。
The events form a candidate execution, on which the memory model acts as a filter. Please consult the memory model for full semantics.
  共享数据块的语义使用内存模型中的共享数据块事件来定义。下方的抽象操做介绍了共享数据块事件以及在内存模型上解析语义和事件语义的接口的行为。事件造成了一个候选执行,内存模型扮演了一个过滤器的角色。请查看内存模型来了解更多的语义。

结语

  到这里就暂时告一段落了,虽然在规范的中段和后段还有不少须要咱们去学习的,之后经验丰富一点再看看能不能继续翻译吧。固然若是有人受此启发愿意去翻译,甚至是翻译css和html的规范那就更好了,W3C的规范有中文版,可是只有最前面1章,好久都没有更新了。

  在最后笔者只是大体的看了一下有没有特别严重的好比排版错误之类的,翻译过程当中确定还存在不少问题,无论是翻译仍是理解,都但愿你们可以多多包涵,也但愿你们可以指出错误,共同进步~

相关文章
相关标签/搜索