【譯】ECMAScript文檔---序言及1-6章(上)

前言

  本系列譯文的初衷旨在但願更多人可以瞭解關於JS的一些基本概念,遇到原理性的問題時多去翻翻文檔,而不是在社區無休止的重複提出某些在文檔中可以很是方便快捷就能找到的東西。css

  精力和水平有限,因此暫時只打算嘗試翻譯前面幾章歸納性的介紹,同時後面的章節大多都是步驟形式的僞代碼或者實現流程,按照這些步驟一步一步推敲便可。好比,要查xxx和xxx進行==比較時究竟是怎麼樣進行的,就能夠直接看規範7.2節,我的認爲,比看文章,記憶總結出來的圖表,都更直觀且有說服力。html

  因爲筆者水平有限,知識的深度和廣度也不是很夠,僅僅是出於上面提到的初衷纔想去作這件事。翻譯過程定會存在諸多疏漏與錯誤,還望批評指正~git

因爲單篇文章有長度限制(最後我才知道,由於以前在本地md編輯器裏面寫。。),因此分爲兩篇文章來發布。另外數學公式有些語法sf並不支持,好比行類公式,可是爲了表達準確沒有刪除,你們儘可能理解,抱歉抱歉。程序員

下面開始正文。github

簡介

  Ecma標準定義了ECMAScript 2018語言。它是ECMAScript語言規範的第9版。自從在1997年發佈第1版以來,ECMAScript已經成長爲世界上最爲普遍使用的編程語言之一。由於被內嵌入web瀏覽器而被普遍熟知,可是一樣也普遍地適用於服務端和嵌入式應用程序。web

  ECMAScript基於幾項原始的技術,其中最爲熟知是Netscape的JavaScript和Microsoft的JScript。ECMAScript是Brendan Eich在Netscape公司的時候被髮明的,第一次出現則是在他們公司的Navigator 2.0瀏覽器上。隨後,它出如今Netscape公司以後的瀏覽器,以及從微軟從IE 3.0起發佈的全部瀏覽器上。正則表達式

  而ECMAScript語言規範的發展則要追溯到1996年的那個11月。Ecma標準的第1版在1997年7月的Ecma大會上被表決接受。編程

  Ecma標準在"快速通道"的幫助下被提交給ISO/IEC JTC 1,並在1998年的4月底ISO/IEC 16262會議上投票經過做爲國際標準。1998年6月的Ecma大會投票經過了ECMA-262的第2版,使之與ISO/IEC 16262保持一致。第1版與第2版的區別是社論性質的。windows

  標準的第3版介紹了強大的正則表達式,更好的字符串處理,新的控制語句,try/catch異常處理,更嚴格的錯誤定義,數字輸出格式化,以及一些其餘的隨着語言的發展在將來可能出現的一些微小的變化。ECMAScript規範的第3版在1999年12月被Ecma委員會採用,並於2002年6月在ISO/IEC 16262:2002上發佈。數組

  在發佈了第3版以後,ECMAScript和萬維網獲得了巨大的承認和結合,本質上它已經成爲了被全部瀏覽器支持的編程語言。同時,開發ECMAScript第4版的工做也已完成。然而,那些工做的成果是不完整的,也沒有被做爲ECMAScript的第4版發佈。可是其中的一部分被合併進了第6版之中。

  ECMAScript的第5版(做爲ECMA-262第5版發佈)將那些在瀏覽器實現中已經很常見的語言規範做爲事實性的解釋寫進了規範。而且增長了對那些自從第3版發佈以來的新特性的支持。這樣的新特性包括,訪問器屬性(即get,set,enumerable,configurable),reflective creation and inspection of objects,對數據屬性的控制(即value,writable,enumerable,configurable),更多的能夠操做數組的函數(map,reduce等),支持JSON對象編碼格式,支持提供了增強了的錯誤檢查和程序安全檢查的嚴格模式等等。第5版被2009年12月的Ecma大會所採納。

  第5版被提交給ISO/IEC JTC 1,而且在2011年的ISO/IEC 16262:2011上被做爲國際標準被經過。ECMAScript標準的5.1版進行了一些小的修正,並與ISO/IEC 16262:2011保持一致。第5.1版在2011年6月底Ecma大會上被採納。

  備受關注的第6版的開發於2009年開始,當時第5版正準備發佈。然而,一些重大的實驗和那些能夠追溯到1999年第3版的發佈時的語言加強方面的設計工做卻使得第6版領先於第5版。

  從真正意義上來說,第6版的完成將這15年來的努力推向了頂峯。增長這些東西的初衷和目標有不少,包括對大型應用提供更好的支持,庫(library)的建立,還有將ECMAScript做爲其餘語言的編譯結果的用法。同時,也包括一些重大的加強,如模塊系統,類(class)聲明,詞法塊級做用域,迭代器(iterator)和產生器(generator),爲異步編程而生的promise,解構,以及適當的尾部調用。

  ECMAScript中內置的庫得以擴充,目的是提供更多的數據抽象功能。如,map,set,數組二進制操做(TypedArray),字符串填充(`aa ${xx}`),正則表達式改進。內置庫一樣也經過子類來擴充。第6版是增量式的語言和庫加強,於2015年6月在大會上被採納。

  ECMAScript規範是Ecam TC39的第一個發佈版,新的發佈策略將會每一年發佈一次新版本,而且公佈進展過程。純文本的源文檔從ECMAScript 2015源文檔開始時在Github上創建,目的是爲更進一步的發展提供一個基礎。

  在標準發展的這些年,提交了數以百計的pr和issue,它們爲咱們修復了不少bug,編輯錯誤以及其餘方面的提高。除此以外,衆多的軟件工具被創造,幫助了咱們。如Ecmarkup, Ecmarkdown, 以及Grammarkdown。規範同時也提供了對新的求冪運算符(**)的以及數組的includes方法的支持。

  表明不一樣組織的衆多我的也爲Ecma TC39如今及以前的發展作出來不少顯著的貢獻。除此以外,也出現了一個支持TC39併爲ECMAScript努力的充滿活力的社區。這個社區review了大量的草案,報告了大量的bug,並對實現進行了實驗,貢獻了測試相關的工具,使全世界的ECMAScript的開發者從中受益。原諒咱們,沒法對這些作出努力的貢獻者們一一感謝。

Allen Wirfs-Brock
ECMA-262第6版編輯

Brian Terlson
ECMA-262第7版編輯

譯註:除了上面提到的兩個,其實tc39的成員真的個個都很是厲害,他們來說微軟,谷歌,mozilla,facebook等等等等,若是你常常watch的話,就會發現這些人真的值得學習,你可能在whatwg,css,各類規範/協議的地方都能找到他們的身影,他們有的人gh上並無太多東西,可是卻絲毫掩蓋不了他們的智慧。因此,多找找差距,加油吧,不要再進行無心義的撕逼了~(最後一句實際上是好幾個月前寫的。。)

1. 規範的範圍

  本規範定義了ECMAScript 2018通用程序語言。

2. 合法性

  一個合法的ECMAScript標準的實現必須提供和支持全部的類型,值,對象,屬性,函數以及本規範中描述的程序語法及語義。

  一個合法的ECMAScript標準的實現必須採用最新版本的Unicode標準和ISO/IEC 10646標準統一且一致的解釋輸入的源文本(代碼)。

  一個提供了應用程序接口的合法的ECMAScript標準的實現,須要在這些接口中,支持不一樣天然語言和國家的人們的語言和文化傳統。同時必須實如今ECMA-402最新版中定義的與本規範兼容的接口。

  一個合法的ECMAScript標準的實現也許會提供額外的類型,值,對象,屬性以及那些超過當期規範的函數(譯註:即將來版本)。特別要注意的是,這些實現也許會提供某些在規範中有描述的對象的在規範中描述的屬性以及這些屬性對應的值。

  一個合法的ECMAScript標準的實現也許會支持一些沒有在規範中說起的程序或者正則表達式語法。特別的來講,一個合法的ECMAScript標準的實現也許會支持一些利用將來的保留字的語法。

  一個合法的ECMAScript標準的實現絕對不能實現任何在16.2節中列出的禁止的擴展

3. 規範中的參考文獻

  下面的文檔連接對於本規範的應用程序是必不可少的。對於標註了日期的引用,表明只適用於標註的那個版本。對於沒有標註日期的引用,則適用於最新的版本(包括修正案)。

  ISO/IEC 10646:2003:信息技術 - 通用多八位(Multiple-Octet)編碼字符集,以及2005修正案12006修正案22008修正案32008修正案4,以及額外的修正案,勘誤,後續標準。

  ECMA-402,ECMAScript 2015國際化API規範

  ECMA-404,JSON數據交換格式

4. 概述

  這一節對ECMAScript語言進行一個不太規範的概述。

  ECMAScript是一門面向對象的程序語言,目的是在宿主環境中計算和操做那些計算的東西。這裏定義的ECMAScript的意圖並非本身給本身定下計算規則,事實上,規範中並無規定輸入的外部數據,以及該輸出怎樣的計算結果。

  事實上,咱們指望ECMAScript的計算環境不只可以提供對象和其餘咱們描述的事物,並且可以提供某些具體環境下的對象,關於這些對象的描述和行爲已經超出了本規範的職責範圍,除非它們能提供某些能夠在ECMAScript語言中被訪問的屬性和函數(譯註:如全局對象,不一樣瀏覽器特有的某些對象)。

  ECMAScript最初被設計用來做爲一門腳本語言,可是如今已經被普遍地做爲一門通用語言使用。腳本語言是一門被用做計算,定製以及自動化處理現有系統中的各個元素的程序語言。在這樣的系統中,經過用戶接口咱們已經能得到不少有用的功能,腳本語言就是爲了將這些功能暴露給程序去控制的一種機制。經過這樣的方式,現有的系統可以爲這些對象和元素提供一個宿主環境,腳本語言才能發揮本身的功能。一門腳本語言是爲專業的和非專業的程序員使用的。

  ECMAScript最初是被設計爲一種Web腳本語言,目的是提供一種讓Web頁面更加富有生機的機制,而且可以在基於Web的客戶端-服務端架構(譯註:即BS架構)下作一些本來要在服務端進行的計算。ECMAScript如今被用做在各類各樣的宿主環境中提供核心腳本功能。所以,本文檔描述的是除了任何特定的宿主環境外的語言核心自己。

  ECMAScript的用法已經遠遠超過了普通的腳本語言,如今它被用做許多不一樣環境下的編程任務的各個方面。隨着ECMAScript用法的擴充,它也擁有愈來愈多的特性。如今,ECMAScript已是一門功能完備的通用語言。

  一些ECMAScript的功能與其餘咱們使用的程序語言是類似的,特別是下面描述到的C,$JAVA^{TM}$,Self以及Scheme:

  ISO/IEC 9899:1996, Programming Languages – C

  Gosling, James, Bill Joy and Guy Steele. The Java™ Language Specification. Addison Wesley Publishing Co., 1996.

  Ungar, David, and Smith, Randall B. Self: The Power of Simplicity. OOPSLA '87 Conference Proceedings, pp. 227-241, Orlando, FL, October 1987.

  IEEE Standard for the Scheme Programming Language. IEEE Std 1178-1990.

4.1 Web腳本

  Web瀏覽器爲客戶端計算提供了一個ECMAScript宿主環境,這些計算包括不少,例如,表明窗口(windows),菜單,彈出框,對話框,文本域,錨點,frame,history,cookies以及輸入輸出的對象。

  進一步來講,宿主環境提供了一種方式,可以將腳本代碼附加到諸如焦點改變,頁面和圖片加載、卸載、錯誤、中斷,選擇某個區域,表單提交,鼠標動做這樣的事件上。腳本代碼出如今HTML以及展現的頁面裏,是一種與那些用戶接口元素,固定的或者計算後的文本,以及圖片的結合。腳本代碼對用戶交互進行響應,對主程序是沒有必要的。

  Web服務器則爲服務端計算提供不一樣的宿主環境,例如,表明請求(requests),客戶端(clients),文件的對象。以及鎖住和共享數據的機制。經過瀏覽器端和服務端腳本的共同使用,咱們可以對基於Web的應用程序提供自定義的用戶接口,從而讓在客戶端和服務端上的計算達到一個平衡。

  每個支持ECMAScript的Web瀏覽器和服務器提供了屬於它們本身的宿主環境,從而完善ECMAScript執行環境。

4.2 ECMAScript概述

  如下是一個ECMAScript的非正式的概述-並不會描述語言的全部部分。這個概述不是標準的一部分。

  ECMAScript是基於對象的:語言的基礎和宿主功能都經過對象的方式提供,一個ECMAScript程序是一個互相有聯繫的對象的集羣。在ECMAScript中,一個對象是一個集合,這個集合包含0到多個屬性,每一個屬性定義了這個屬性是用來作什麼的。例如,當一個屬性的Writable屬性被設置爲false的時候,任未嘗試去給這個屬性賦值爲與以前不一樣值的ECMAScript代碼都不會成功。屬性是控制其它對象,原始值或者函數的容器。一個原始值是下列內置類型之一:Undefined, Null, Boolean, Number, String, 以及Symbol。一個對象(object)屬於Object這種內置類型。一個函數(function)是一個可調用的對象。一個函數經過一個叫作method的屬性與一個對象相關聯。

  ECMAScript定義了一系列的內置對象,用於完成對ECMAScript實體的定義。這些內置對象包括全局對象,以及語言的運行時語義基本對象,它們包括Object, Function, Boolean, Symbol,不一樣的Error對象(譯註:如ErrorSyntaxErrorTypeError等等),表明和操做數值的Math, NumberDate。處理文本的StringRegExp,創建索引來存儲對象的集合的Array,9種不一樣類型的Typed Arrays(譯註:Int8Array()Uint8Array()Uint8ClampedArray()Int16Array()等等),有鍵值的集合MapSet,支持結構化數據的JSONArrayBuffer, SharedArrayBuffer, DataView,支持控制抽象的generator函數,Promise,最後是反射對象ProxyReflect

  同時ECMAScript也定義了一系列的內置操做符。ECMAScript操做符包括一元操做符,乘法操做符,加法操做符,位運算操做符(譯註:即<<>>>>>),關係操做符(譯註:即>>=<<=instanceofin),相等操做符,二進制位操做符(譯註:即^&|),二進制邏輯操做符(譯註:即&&||),賦值操做符,逗號操做符。

  大型的ECMAScript程序須要模塊的支持,它容許一個程序被劃分爲多個語句和聲明的序列。每一個模塊顯式地識別它用到的由其它模塊提供的聲明,同時它本身內部的聲明也能被其餘模塊所用。(譯註:這裏的聲明是指importexport這種,而不是變量聲明)

  ECMAScript語法有意地模仿了Java語法(譯註:這一句和後面的應該沒有聯繫,是單獨的兩句話)。ECMAScript語法是寬鬆的,能夠激活它做爲一門易於使用的腳步語言。例如,一個變量不須要進行類型聲明,它的屬性也與類型不相關聯(譯註:應該是指一個能夠前後將不一樣類型的值賦值給同一個變量),函數聲明沒必要出如今函數調用以前。

4.2.1 對象(Objects)

  儘管ECMAScript包含了定義一個類的語法,可是ECMAScript對象從根本上來講並非像C++,Smalltalk,Java那樣基於類的。對象能夠經過多種方式建立,如經過字面量或者構造函數建立,而後執行初始化全部或者部分屬性的代碼。構造函數是一個擁有"prototype"屬性的函數,"prototype"被用做實現基於原型的繼承以及共享屬性。對象經過構造函數在new表達式中建立,new Date(2009,11)建立一個Date對象。不經過new的方式調用一個構造函數會產生一些後果,這些後果由那個構造函數決定。例如,直接調用Date()會產生一個表示當前日期的字符串,而不是一個對象。

圖1 Object/Prototype 關係

  每一個經過構造函數建立的對象都有一個隱式的引用(被叫作對象的原型)指向構造函數的"prototype"屬性。除此以外,一個原型也許有一個非null的隱式引用指向它本身的原型,這樣的層層傳遞,被稱做原型鏈。當一個引用指向一個對象中的某個屬性的時候,那個引用就指向在原型鏈中第一個含有這個引用名的對象。換句話說,首先會檢查這個對象自己是否含有那個屬性,若是有,那麼這個引用就指向那個屬性,若是沒有,就去這個對象的原型中檢查,而後重複這些步驟。

  一般,在一個基於類的面嚮對象語言中,狀態被實例所持有,方法被類所持有,繼承只是結構和行爲。在ECMAScript中,狀態和方法都被對象所持有,結構,行爲,狀態都被繼承。

  全部非對象自身的屬性,都經過對象的原型來共享屬性以及屬性的值,圖1解釋了這一切:

  CF是一個構造函數(同時也是一個對象)。這裏經過new操做符已經建立了5個對象(譯註:即new CF()):cf1cf2cf3cf4,以及cf5。這5個對象中的每個都包含了q1q2屬性(譯註:即執行了cf1.q1=xxx,cf2.q1=xxx)。虛線展現了隱式的原型關係。因此,例如,cf3的隱式原型是CFp(譯註:即cf3.__proto__或者Object.getPrototypeOf(cf3)都等於CFp)。構造函數CF有兩個它自己的屬性P1P2,對於CFpcf1cf2cf3cf4,以及cf5來講都是不可見的(譯註:即沒法經過CFP.p1,cf1.p2這樣的方式訪問,這裏的P1和P2是指的CF.P1=xxxCF.P2=xxx,即靜態/static屬性,不要理解成在CF這個構造函數裏寫this.P1=xxxthis.P2=xxx,那樣叫作實例屬性)。原型(即CFp)上的CFP1屬性被cf1cf2cf3cf4,以及cf5共享(可是不被CF共享,(譯註:即沒法經過CF.CFP1訪問)),任何在CFp的隱式原型鏈中的屬性也遵循這樣的規則,注意在這裏CFCFp之間沒有隱式的原型引用(譯註:正由於如此,因此CF.CFP1才爲undefined,CF的隱式原型是Function.prototype)。

  不一樣於大多數基於類的語言,ECMAScript經過給對象的某個屬性賦值,能夠動態的給對象添加屬性。也就是說,構造函數並非惟一的能夠給構造出來的對象添加屬性的方式。在上圖中,咱們能夠經過給CFP添加一個新的屬性,從而達到給cf1cf2cf3cf4,以及cf5新增一個共享的屬性。

  儘管ECMAScript對象本質上不是基於類的,咱們仍是能夠基於一個常見的模式,即構造函數,原型對象以及類方法來很方便的定義"模擬類"(class-like,譯註:即相似於類這種結構,與類數組概念相仿,這裏的"模擬類"是筆者本身想的,若是有更好的表述,歡迎指正)抽象。那些ECMAScript內置對象也遵循這樣的"模擬類"模式(譯註:即也是經過構造函數,原型對象以及類方法來定義的)。從ECMAScript 2015開始,ECMAScript語言包含了類定義語法,容許程序員簡潔的定義符合"模擬類"抽象模式的對象,內置對象也採起了這種方式來定義。

4.2.2 ECMAScript嚴格變體(The Strict Variant of ECMAScript)

  ECMAScript語言意識到也許有些ECMAScript語言的用戶會但願可以在語言中約束某些特性的用法。他們這麼作也許是出於安全考慮,避免讓他們考慮那些容易出錯的特性,從而增強錯誤檢查,或者是因爲其它緣由它們想這麼作。爲了支持這樣的選擇,ECMAScript定義了一個語言的嚴格變體。這個語言的嚴格變體除去了某些常規的ECMAScript語言擁有的特定的語法和語義特性,而且修改了某些特性的具體語義。嚴格變體也指定了額外的錯誤條件,它們必須經過拋出錯誤異常來報告,在語言的非嚴格模式下是沒有指定的這些錯誤的。

  ECMAScript的嚴格變體一般被稱爲語言的嚴格模式。嚴格模式的選擇,以及嚴格模式語法和語義的使用,是以單個的ECMAScript源文本做爲單位的。由於嚴格模式是在語法源文本單元這個層級上選擇,嚴格模式只會給在這樣的源文本單元內有局部影響的文本加上限制。嚴格模式並不限制或者修改任何ECMAScript語義方面的東西,語義必須在多個源文本之間都是一致的。一個完整的ECMAScript程序也許即存在嚴格模式又存在非嚴格模式的ECMAScript源文本單元。在這樣的狀況下,嚴格模式只適用於執行定義在嚴格模式內的源代碼文本單元。(譯註:如

function foo(){
  function bar1(){
    'use strict'
     console.log(this);
  }
  bar1();
  
  function bar2() {
    console.log(this);
  }
  bar2();
}

只有bar1纔會輸出undefined)。

  爲了遵循這個規範,一個ECMAScript實現必須即實現完整的非嚴格模式的ECMAScript語言,同時也實現本規範定義的ECMAScript語言的嚴格變體。除此以外,一個實現必須支持非嚴格模式和嚴格模式的源代碼文本單元的混合,把它們變成一個單一的複合程序。

4.3 術語及定義(Terms and Definitions)

  出於本文檔的須要,規定了如下術語和定義。

4.3.1 類型(type)

  指定義在本規範的條款6中的數據值的集合

4.3.2 原始值(primitive value)

  指定義在條款6中的Undefined, Null, Boolean, Number, Symbol,以及String的其中之一的成員

注:一個原始值是直接表明本語言實現的最低層級的基準

4.3.3 對象(object)

譯註:從這裏開始,會出現「注」,這是規範裏自己所含有的,並非筆者添加的注,筆者添加到注會寫明「譯註」二字,請注意區分。原文爲NOTE,這裏翻譯爲了「注」,

  指Object類型的成員

注:一個對象是一個屬性的集合,而且只有一個惟一原型對象。原型對象可能爲null

4.3.4 構造函數/構造器(constructor)

  指建立和初始化對象的函數對象

注:構造函數的prototype屬性是一個被用來實現實現繼承和共享屬性的原型對象

4.3.5 原型(prototype)

  指一個爲其它對象提供共享屬性的對象

注:當一個構造函數建立一個對象時,出於解析屬性引用的目的(譯註:即讓obj.foo和obj['foo']可以工做),那個對象將隱式的引用構造函數的prototype屬性。構造函數的prototype屬性可以經過表達式constructor.prototype被引用,而且添加到原型上的屬性可以被共享,經過繼承,全部對象共享原型。再者,經過使用使用內置的Object.create函數,一個對象能夠被顯式地指定某個原型來建立。

4.3.6 普通對象(ordinary object)

  指擁有必須被全部對象支持的相當重要的內部方法的默認行爲的對象。

4.3.7 外來對象(exotic object)

  指那些沒有一個或多個相當重要的內部方法的默認行爲的對象。

注:任何對象不是普通對象就是外來對象

4.3.8 標準對象(standard object)

  指那些語義是由本規範定義的對象。

4.3.9 內置對象(built-in object)

  指那些由ECMAScript的實現指定和提供的對象。

注:標準的內置對象被定義在本規範中。一個ECMAScript實現也許會指定和提供額外的某些內置對象。一個內置構造函數是一個內置對象,同時也是一個構造函數。

4.3.10 undefined值(undefined value)

  是一個原始值(primitive value),表明當一個變量還未被賦值。

4.3.11 Undefined類型(Undefined type)

  是一個類型,它的惟一值是undefined

4.3.12 null值(null value)

  是一個原始值,表明任何對象值的有意缺省。

4.3.13 Null類型(Null type)

  是一個類型,它的惟一值是null

4.3.14 Boolean值(Boolean value)

  指Boolean類型的成員之一

注:Boolean類型只有兩種值,truefalse

4.3.15 Boolean類型(Boolean type)

  指包含原始值truefalse的類型。

4.3.16 Boolean對象(Boolean object)

  是Object類型的成員之一,是標準的內置Boolean構造函數的實例。

一個Boolean對象經過使用Boolean構造函數在new表達式中建立,接收一個Boolean值做爲參數。返回的結果對象有一個內部的slot(slot在第六章會解釋),它的值是一個Boolean值。一個Boolean對象可以被轉換爲一個Boolean值。(譯註:即拆箱)

4.3.17 String值(String value)

  是一個原始值,是一個由0至多個16bit的無符號數字值組成的有限的有序序列。(譯註:即每一個字符都由2個字節組成,固然,存在由4個字節組成的字符,這裏說的只是js內部的字符串的表示)

一個String值是一個String類型的成員。在上面提到的序列中的每一個整數(0-65535)一般表明UTF-16文本中一個單一的16bit單元。

4.3.18 String類型(String type)

  全部可能的String值的集合。

4.3.19 String對象(String object)

  是Object類型的成員之一,是標準的內置String構造函數的實例。

一個String對象經過使用String構造函數在new表達式中建立,接收一個String值做爲參數。返回的結果對象有一個內部的slot,它的值是一個String值。一個String對象可以經過調用String構造函數(String(xxx)而不是new String(xxx))轉換爲一個String值。

4.3.20 Number值(Number value)

  是一個原始值,與IEEE-754-2008規範的雙精度64bit二進制格式相對應。

一個Number值是一個Number類型的成員,是一個數字的直接表示。

4.3.21 Number類型(Number type)

  是一個全部可能的Number值的集合,包括NaN,正的Infinity以及負的Infinity

4.3.22 Number對象(Number object)

  是Object類型的成員之一,是標準的內置Number構造函數的實例。

一個Number對象經過使用Number構造函數在new表達式中建立,接收一個Number值做爲參數。返回的結果對象有一個內部的slot,它的值是一個Number值。一個Number對象可以經過調用Number構造函數(Number(xxx)而不是new Number(xxx))轉換爲一個Number值。

4.3.23 Infinity

  是一個Number值,指正的Infinity

4.3.24 NaN

  是一個Number值,指IEEE 754-2008中的「Not-a-Number」值。

4.3.25 Symbol值(Symbol value)

  是一個原始值,表明一個惟一的,非字符串的對象的屬性的鍵(key)。

4.3.26 Symbol類型(Symbol type)

  全部可能的Symbol值的集合

4.3.27 Symbol對象(Symbol object)

  是Object類型的成員之一,是標準的內置Symbol構造函數的實例。

4.3.28 函數(function)

  是Object類型的成員之一,也許會做爲一個子例程被調用。

除了它的屬性外,一個函數包含可執行的代碼和決定當被調用時的行爲的狀態。一個函數的代碼可能會也可能不會是ECMAScript書寫的。

4.3.29 內置函數(built-in function)

  指那些是函數的內置對象。

這樣的例子包括parseIntMath.exp。一個ECMAScript的實現也許會提供沒有在本規範中描述的依賴於實現的內置函數。

4.3.30 屬性(property)

  是對象的一部分,關聯鍵(要麼是一個字符串,要麼是一個Symbol值)和值

取決於屬性的格式,屬性的值可能做爲一個數據值(一個原始值,一個對象,或者一個函數是對象)直接被展現,或者間接地經過一對訪問器函數展現。

4.3.31 方法(method)

  是一個函數,指某個屬性的值。(譯註:即method是function的真子集)

當一個函數被做爲一個對象的方法調用時,這個對象將做爲這個函數裏的this值被傳遞到這個函數中。

4.3.32 內置方法(built-in method)

  是一個內置函數的方法

標準的內置方法被定義在本規範中,而且ECMAScript實現也許會指定和提供其它的額外的內置方法。

4.3.33 屬性(attribute)

  指定義某些屬性(property)的特徵的內部值

4.3.34 自有屬性(own property)

  指被對象直接全部的屬性(property)

4.3.35 繼承屬性(inherited property)

  指對象的屬性但非自有屬性,是對象的原型的屬性(即原型上的自有屬性或者繼承屬性)。

4.4 本規範的章節組織(Organization of This Specification)

  本規範剩餘部分的組織以下:

  第5章定義了在本規範中使用的一些符號或者語法的約定。

  第6-9章定義了ECMAScript程序操做包含的執行環境。

  第10-16章定義了實際的ECMAScript語言,包括它的語法編碼以及語言特性的執行語義。

  第17-26章定義了ECMAScript標準庫。它們包括全部當ECMAScript程序執行時可用的標準對象的定義。

5 符號約定(Notational Conventions)

5.1 語法和詞法的文法(Syntactic and Lexical Grammars)

5.1.1 上下文無關文法(Context-Free Grammars)

  一個上下文無關文法由一系列的產生式(productions)組成。每一個產生式包含一個稱做非終結符的抽象的符號做爲它的左值,以及一系列的0個或多個非終結符和終結符做爲它的右值。對於每個文法,終結符都來自一個具體的字符表(譯註:即符號表)。

  一個文法鏈是一個只含有一個非終結符以及0個或多個終結符做爲它的右值的文法。

  從一個包含一個單一的被稱做目標符號的非終結符開始,給出一個指定語言的上下文無關文法。換句話說,全部可能的能由重複地用非終結符在左值的產生式的右值替換這個序列中的任意非終結符推導出的終結符序列。

5.1.2 詞法和正則文法(The Lexical and RegExp Grammars)

  一個ECMAScript的詞法文法在條款11中給出。這個文法有它的符號定義在10.1節中的SourceCharacter規則的終結符的Unicode碼點。它定義了一系列的終結符,從目標符號InputElementDiv,InputElementTemplateTail,或者InputElementRegExp,InputElementRegExpOrTemplateTail,它們描述了像這樣的碼點的序列是如何被翻譯成一系列的輸入元素的。

  除了空白符和註釋以外的輸入元素構成了ECMAScript語法文法的終結符,它們被稱做ECMAScript tokens。這些token是ECMAScript語言的保留字,標識符,字面量以及標點符號。此外,儘管行終結符不被看成是token,可是它也是輸入元素流中的一部分,而且引導着自動分號插入機制。簡單的空白符以及單行註釋都被丟棄而且不會出如今語法文法的輸入元素流中。一個多行註釋(也就是說,形如/*…*/,無論佔據一行仍是多行)也一樣地被丟棄,若是它沒有包含行總結符的話。可是若是一個多行註釋包含了一個或者多個行終結符,那麼它就會被替換成一個單一的行終結符,從而成爲語法文法輸入元素流中的一部分。

  一個ECMAScript的正則文法在21.2.1中給出。這個文法也包含它的定義在SourceCharacter的碼點的終結符。它定義了一系列的產生式,從目標符號的Pattern開始,描述了這樣的碼點的序列是如何被翻譯成正則表達式的pattern的。

  詞法和正則文法的產生式被用兩個冒號做爲分割符(即::)來區分。詞法和正則文法共享一些產生式。

5.1.3 數字字符串文法(The Numeric String Grammar)

  這是另外一個被用做翻譯字符串爲數字值的文法(譯註:即將字符串轉換爲數字)。這個文法與詞法文法中的一些部分是類似的,都須要與數字字面量相協做,而且有它的終結符SourceCharacter。這個文法出如今7.1.3.1中。

5.1.4 語法文法(Syntactic Grammar)

  ECMAScript的語法詞法在條款11,12,13,14以及15中給出。這個文法包含在詞法文法中定義的ECMAScript tokens做爲它的終結符。它定義了一系列的產生式,從兩個可選的目標符號Script以及Module開始,描述了造成ECMAScript程序語法上正常的獨立的組件的token是怎樣的序列。

  當一個碼點流將要被解析成一個ECMAScript的Script或者Module時,它首先經過重複的與詞法文法有關的應用程序被轉換成一個輸入元素流。而後這個輸入元素流被解析成一個單一的語法文法的應用程序。若是在這個輸入元素流中的token不能被解析成一個單一的目標非終結符(Script或者Module)的話,這個輸入流在語法上就是錯誤,將不會留下任何的token。

  當一個解析成功的時候,它會構造一顆解析樹(parse tree),一顆有根的樹的結構是它的每一個節點(Node)都是一個Parse節點。每一個Parse節點是一個文法中的符號的實例。它表明了一個對於那些能從這樣的符號中派生出來的源代碼文本的跨度。解析樹的根節點表明着整個的源代碼文本,是一個解析的目標符號的實例。當一個Parse節點是一個非終結符的實例的時候,它也是一個某些將這個非終結符做爲左值的產生式的實例。此外,它有0個或多個children,產生式右值中的每一個符號:每一個child都是一個是相應符號的實例的Parse節點。

  語法文法的產生式被用一個冒號做爲分割符(即:)來區分

  語法文法在條款12,13,14以及15中提出。可是對於哪些token序列是正確的被ECMAScript Script或者Module接受的解釋得並不完整。一些額外的token序列也能被接受,換句話說,那些序列將會被文法描述,只要分號被加入到序列中的某些地方(好比在行終結符以前)。此外,某些經過文法描述的token序列不會被接受,若是一個行終結符出如今某些「尷尬」的地方。

  在某些案例中,爲了不歧義,語法文法使用廣義的產生式,容許token序列不造成一個合法的ECMAScript Script或者Module。例如,這項技術
被用做對象字面量和對象解構模式中。在這樣的場景中,更多的限制性的補充的文法被提供,進一步限制了可接受的token序列。在某些上下文中,當顯式地指定時,輸入元素相似於一個用補充的語法的目標符號進行再次解析的產生式。若是被解析的輸入元素流中的token經過一個覆蓋的不能被做爲一個單獨的與之對應的補充的目標符號的實例去解析,輸入流就是語法上錯誤的,將再也不保留token。

5.1.5 文法符號(Grammar Notation)

  詞法,正則以及數字字符串文法的終結符用固定寬度的字體展現,無論是在文法的產生式,仍是在本規範中,不管什麼時候,只要文本直接地指向了這樣的終結符。這些都會出如今咱們的寫的腳本中。全部經過這種方式指定的終結符碼點都被看成合適的Unicode碼點理解,從基本的Latin範圍,與之相對的是任意相似的Unicode範圍的碼點。

  非終結符用斜體展現。一個非終結符的定義(也叫作產生式)經過下面定義的一個或多個冒號的非終結符的名稱的方式來介紹。(冒號的數量暗示了這個產生式屬於哪一種文法)。一個或者多個可選的非終結符的右值跟在succeeding線後面。例如,語法定義以下:

WhileStatement:
    while(Expression)Statement

  非終結符WhileStatement的狀態表示了while這個token,隨後是一個左括號token,而後是一個表達式(Expression),而後是一個右括號token,而後是一個語句(Statement)。這些表達式和語句的出現也是非終結符。另外一個例子,語法定義以下:

ArgumentList:
    AssignmentExpression
    ArgumentList,AssignmentExpression

  一個ArgumentList也許表明了一個單一的AssignmentExpression或者一個ArgumentList,而後是一個逗號,而後是一個AssignmentExpression。這個ArgumentList的定義是遞歸的,也就是說,它是根據它自己來定義的。這樣的結果就是,一個ArgumentList也許會包含任意數量逗號分隔的arguments,其中的每一個argument表達式是一個AssignmentExpression。這樣的非終結符的遞歸定義是很是常見的。

  下面的下標後綴「opt」(譯註:因爲在代碼塊中沒法使用<sub>標籤,因此opt沒有展現成下標的形式,可是實際上它是下標),也許會出如今一個終結符或者非終結符後,做爲一個可選的標誌。這個可供選擇的包含一個可選符號的符號,實際上指定2個右值,一個省略了這個可選元素,一個包含了這個可選元素。這意外着:

VariableDeclaration:
    BindingIdentifier Initializer opt

  是下面的縮寫:

VariableDeclaration:
    BindingIdentifier
    BindingIdentifier Initializer

  還有好比:

IterationStatement:
    for(LexicalDeclaration Expression opt ; Expression opt)Statement

  是下面的縮寫:

IterationStatement:
    for(LexicalDeclaration ; Expression opt)Statement
    for(LexicalDeclaration Expression ; Expression opt)Statement

  它們依次是下面的縮寫:

IterationStatement:
    for(LexicalDeclaration ;)Statement
    for(LexicalDeclaration ; Expression)Statement
    for(LexicalDeclaration Expression ;)Statement
    for(LexicalDeclaration Expression ; Expression)Statement

  因此,在這個例子中,非終結符IterationStatement實際上有4個可選的右值。

  一個產生式也許會經過形如「[parameters]」這樣的下標註釋被參數化,它們也許會做爲後綴出如今產生式定義的非終結符中。「parameters」也許是單獨的名稱,或者一個逗號分隔的名稱列表。一個被參數化的產生式是一系列定義參數名稱的全部組合的產生式的縮寫,如下劃線開頭,被追加到參數化的非終結符後面。這就意味着:

StatementList[Return]: (注意這裏的[Return]是下標)
    ReturnStatement
    ExpressionStatement

  是下面的縮寫:

StatementList:
    ReturnStatement
    ExpressionStatement
    
StatementList_Return:
    ReturnStatement
    ExpressionStatement

  再好比:

StatementList[Return, In]:
    ReturnStatement
    ExpressionStatement

  是下面的縮寫:

StatementList:
    ReturnStatement
    ExpressionStatement
    
StatementList_Return:
    ReturnStatement
    ExpressionStatement

StatementList_In:
    ReturnStatement
    ExpressionStatement

StatementList_Return_In:
    ReturnStatement
    ExpressionStatement

  多個參數產生一個組合後的產生式,可是在一個複雜的語法中,並不必定須要引用它們中的所有內容。

  在一個產生式的右值中引用非終結符也能被參數化,例如:

StatementList:
    ReturnStatement
    ExpressionStatement[+In]

  是下面的縮寫:

StatementList:
    ReturnStatement
    ExpressionStatement_In

  再好比:

StatementList:
    ReturnStatement
    ExpressionStatement[~In]

  是下面的縮寫:

StatementList:
    ReturnStatement
    ExpressionStatement

  一個非終結符引用也許既有一個參數列表,又有一個「opt」後綴,例如:

VariableDeclaration:
    BindingIdentifier Initializer[+In]opt  (注意[+In]和opt都是下標)

  是下面的縮寫:

VariableDeclaration:
    BindingIdentifier
    BindingIdentifier Initializer_In

  給一個參數在右值的非終結符引用加上前綴「?」使得那個參數依賴於引用當前產生式左值符合的參數名,例如:

VariableDeclaration[In]:
    BindingIdentifier Initializer[?In]

  是下面的縮寫:

VariableDeclaration:
    BindingIdentifier Initializer

VariableDeclaration_In:
    BindingIdentifier Initializer_In

  若是一個右值以「[+parameter]」做爲前綴,那麼那個可選的只有在命名的參數在引用產生式的非終結符時被使用時纔可用。若是一個可選的右值以「[~parameter]」做爲前綴,那麼那個可選的只有在命名的參數在引用產生式的非終結符時沒有被使用時纔可用。(譯註:即+表示上下的[]必須同時出現,表示不能同時出現)這意味着:

StatementList[Return]:
    [+Return]ReturnStatement
    ExpressionStatement

是下面的縮寫:

StatementList:
    ExpressionStatement
    
StatementList_Return:
    ReturnStatement
    ExpressionStatement

再好比:

StatementList[Return]:
    [~Return]ReturnStatement
    ExpressionStatement

是下面的縮寫:

StatementList:
    ReturnStatement
    ExpressionStatement
    
StatementList_Return:
    ExpressionStatement

  在一個文法定義中,當單詞「one of」跟隨在一個或多個分號後的時候,表示隨後的一行或多行的終結符是一個可選的定義。例如,ECMAScript的詞法文法包含下列的產生式:

NonZeroDigit :: one of
    123456789

  它僅僅是下面的縮寫:

NonZeroDigit::
    1
    2
    3
    4
    5
    6
    7
    8
    9

  若是短語「[empty]」 出如今一個產生式的右值,它暗示着這個產生式的右值不包含終結符或者非終結符。

  若是短語「[lookahead ∉ set]」 出如今一個產生式的右值,它暗示着若是隨後當即的輸入的token序列是給出的集合中的成員,那麼這個產生式也許不會被使用。這個集合能夠用一個逗號分割的由一到兩個被花括號包裹的元素終結序列的列表表示。爲了方便,這個集合也能夠用非終結符表示,在這種狀況下,它表明全部能由非終結符展開獲得的終結符的集合。若是這個集合包含一個單獨的終結符,那麼短語「[lookahead ≠ terminal]」 也許會被使用。

  若是短語「[no LineTerminator here]」 出如今一個語義文法的產生式的右值中,意味着這個產生式是一個受限的/嚴格的(restricted)產生式:若是一個行終結符(LineTerminator)在輸入流中出如今指定的位置,它也許不會被使用。例如,產生式:

ThrowStatement:
    throw [no LineTerminator here] Expression;

  若是一個行終結符出如今腳本的throw token和表達式(Expression)之間的時候,暗示着這個產生式也許不會被使用。(譯註:經過測試,若是之間插入一個行終結符,會拋出Illegal newline after throw異常)

  除非經過一個受限的產生式禁止一個行終結符的出現,不然任意數量行終結符的出現也許會發生在輸入元素流中任意兩個連續的token之間,而且不影響腳本的語義可接受性。

  當一個詞法文法或者數字字符串文法的產生式中可選部分出現多碼點的token時,意味着碼點序列將會組成一個token。

  一個產生式的右值也許會經過短語「but not」指定某些不被容許的擴展,而後暗示這個擴展將是被排除在外的。例如,產生式:

Identifier ::
    IdentifierName but not ReservedWord

  

  意味着非終結符Identifier也許會被任意的碼點序列替換,這些碼點可以替換提供的IdentifierName,可是相同序列的碼點不能替換ReservedWord。(譯註:即Identifier能夠是除了ReservedWord(保留字)以外的其它任意的IdentifierName)

  最後,一些非終結符經過sans-serif字體書寫的描述性的短語來描述,在這樣的案例中,列出全部的可選部分是不切實際的。(譯註:例以下方的SourceCharacter是一個統稱,實際來講指的太多了,因此不可能一一列出)

SourceCharacter :: (譯註:這裏的SourceCharacter就是sans-serif字體)
    any Unicode code point
相關文章
相關標籤/搜索