【譯】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章,好久都沒有更新了。

  在最後筆者只是大體的看了一下有沒有特別嚴重的好比排版錯誤之類的,翻譯過程當中確定還存在不少問題,無論是翻譯仍是理解,都但願你們可以多多包涵,也但願你們可以指出錯誤,共同進步~

相關文章
相關標籤/搜索