從規範看ECMAScript(一):規範基礎

《從規範看ECMAScript》是筆者將要寫的一系列文章+筆記,目的是從規範底層來看ECMAScript的各類行爲(特點or異常)。html

全部文章都在Github上,歡迎star、watch。git

參考的規範是ECMASCript2018即ES9,地址🔗es6

由於ES9是ES正式的最新版本,於2018年六月發佈。而ECMAScript2019🔗目前的狀態仍是draft(大概19.6轉爲正式)。雖然變更不會太大,仍是以穩定的版本爲準吧。github

ES歷史版本地址🔗,ES最新發布版本地址🔗正則表達式

本文還參考了zhoushengmufc的中文版本ES6(此中文版本未譯全)。在這裏,筆者還要推薦一個Github的項目:engine262🔗。此項目按照規範實現了一個標準的ES的解釋器。(是真的標準,基本徹底符合規範裏的算法步驟,調試調試對理解規範的運行時語義更有幫助。)算法

筆者的文章主要是對ES運行時語義的分析,因此關於其靜態語義講的很少。編程

若是你想完整的閱讀規範,閱讀以前能夠先看看一個大神寫的如何閱讀ES,上面提到的engine262也有他的參與。數組


本文主要介紹規範1~5章,是對ES的總覽和規範裏的記法約定。promise

介紹

ES1th發佈於1997年6月,ES2th發佈於1998年6月,主要是對初版的格式修正。瀏覽器

ES3th引入了正則表達式,更好的字符串處理,新的控制語句,try/catch異常處理,更嚴格的錯誤定義,數字輸出的格式。發佈於1999年12月。

ES3以後ES被萬維網所採用,被大部分瀏覽器所支持。可是因爲關於語言的複雜性出現分歧,ES4th沒有完成。

ES5th增長了一些特性,例如嚴格模式、訪問器屬性、JSON的支持等,發佈於2009年12月。ES5.1對ES5進行了微小的修改,發佈於2011年6月。

ES6th發佈於2015年6月,實際上ES6的集中發展在2009年,而且在1999年出版第三版以前,就進行了大量的實驗和語言加強設計工做,能夠說ES6是十五年努力的結果。發展目標包括更好地支持大型應用程序、庫建立以及將ECMAScript用做其餘語言的編譯目標。

其主要改進爲:模塊、類聲明、詞法做用域、迭代器和生成器、promise異步編程、結構模式、尾調用。擴展了ECMAScript內置庫,以支持額外的數據抽象,包括mapset、二進制數值數組,以及對字符串和正則表達式中Unicode補充字符的額外支持。

ES7th添加了指數運算、Array.prototype.includes。另外從ES7開始ES發佈就是一年一更了(我根據規律猜的😂)。

ES8th引入了Async、共享內存、Atomics 、庫加強、Bug修復。

async函數提供了promise-returning函數,加強了異步編程體驗。

共享內存和Atomics引入了一種新的內存模型,容許多代理程序使用原子操做進行通訊,即便在並行處理器上也能確保定義良好的執行順序。(暫時不太懂)

還增長了Object.values, Object.entries, 和 Object.getOwnPropertyDescriptors

本規範(ES9th)經過異步迭代器協議和異步生成器引入對異步迭代的支持。還引入了四個新的正則表達式特點,還有對象屬性的rest參數和擴展運算符支持。

概述

ECMAScript是一種面向對象的編程語言,用於在宿主環境中執行計算和操做計算對象。

ECMAScript最初被設計成一種Web腳本語言,提供了一種機制來使瀏覽器中的網頁更加有趣,並做爲基於Web的客戶端-服務器體系結構的一部分來執行服務器計算。

ECMAScript如今用於爲各類宿主環境提供核心腳本功能。


這一節有用的就這些,其中宿主環境指瀏覽器或者Node環境等。

Web Scripting

瀏覽器端

Web瀏覽器爲客戶端計算提供了ECMAScript宿主環境,例如:窗口對象、菜單、彈出窗口、對話框、文本區域、連接、框架、瀏覽歷史、cookie、和輸入/輸出。

此外,主機環境提供了一種將腳本代碼附加到事件的方法,例如:焦點改變、鼠標動做等等事件。腳本代碼對用戶交互起反應,不須要主程序。

在瀏覽器端ES主要爲了處理用戶與瀏覽器之間的交互。

服務端

Web服務器爲了服務器端計算提供了一個不一樣的宿主環境,包括請求、文件IO等等。

每一個支持ECMAScript的Web瀏覽器和服務器都提供本身的宿主環境,以完成ECMAScript執行環境。

ECMAScript總覽

ES是基於對象的,基本語言和宿主工具都是由對象提供,ES程序是一組通訊對象

對象是一系列屬性property的集合。每一個屬性的特性attribute決定了屬性行爲。例如其writable 決定其是否可寫,configurable決定其是否可配置,等等。

屬性是一個容納其餘對象、原始值、函數的容器。

原始值(primitive value)有六種類型:UndefinedNullBooleanNumberStringSymbol

函數(function)是可調用(callable)對象。經過屬性與對象關聯的函數稱爲方法(method)。

ECMAScript定義了一組內置對象,這些對象完善了ECMAScript實體的定義。

這些內置對象有

全局(Global)對象;

維持語言運行時語義的基礎的對象: ObjectFunctionBooleanSymbol和各類Error對象;

表示和操控數值的對象:MathNumber、和Date

用於處理文字對象:StringRegExp

值的索引集合的對象:Array,和九種類型的數組,其元素都具備特定的數值數據表示形式;

鍵的集合的對象:MapSet

結構化數據的對象:JSONArrayBufferSharedArrayBufferDataView

控制抽象的對象:生成器函數、Promise

反射對象:ProxyReflect

ECMAScript定義了一系列內置操做符:* / + - >> 等等。

大型ES程序支持模塊(Module)化,容許程序被分紅多個語句和聲明序列。 每一個模塊顯式地標識它使用的須要由其餘模塊提供的聲明,以及它的哪些聲明可供其餘模塊使用。


這節大概講了下ES的類型,內置對象。關於其類型,在第六章會詳細講述。

對象

ES 對象並非徹底基於類的。 能夠經過各類方法,例如字面量定義或構造器(constructor)來建立對象,並對其分配屬性。

每一個構造器都是一個函數,都有一個原型屬性,用來實現基於原型的繼承和屬性共享

構造器建立的對象有一個被稱做對象原型的隱式引用, 指向構造器的prototype屬性。

原型能夠具備對其原型的非空隱式引用,這就是原型鏈

當引用對象中的屬性時,該引用指的是原型鏈中包含該名稱的屬性的第一個對象中該名稱的屬性。首先檢查直接對象的這種屬性; 若是該對象包含命名屬性,則引用該屬性; 若是該對象不包含命名屬性,則接下來檢查該對象的原型。

原型

(上面這張圖你們應該看得懂,我就不解釋了。看不懂的話本文可能不適合你,再瞭解瞭解JS再來看吧。)

在基於類的面嚮對象語言中,一般狀態由實例承載,方法由類承載,繼承僅具備結構和行爲。 在ECMAScript中,狀態和方法由對象承載,而結構,行爲和狀態都是繼承的。

嚴格模式

ES還提供了嚴格模式,嚴格變體排除了常規ECMAScript語言的某些特定句法和語義特徵,並修改了某些特徵的詳細語義。

略述,詳細內容🔗

術語和定義

這小節定義了許多術語,例如類型、原型、原始值、構造器等,還有stringnumber這些值的範圍等等,詳細內容🔗

講幾個很差理解的術語,對象的四種類型:

  • ordinary object普通對象:對象具備全部對象支持的基本內部方法。
  • exotic object怪異對象:沒有一個或多個基本內部默認方法的對象。(任何不是普通對象的對象都是非普通對象。)
  • standard object標準對象:其語義由本規範定義。標準對象能夠是普通對象,也能夠是怪異對象。
  • built-in object內置對象:按照ECMAScript實現的對象。標準內置對象在本規範中定義。 ECMAScript實現(例如JS、Node)能夠指定和提供附加種類的內置對象。 內置構造函數是一個內置對象,也是一個構造函數。全部的標準對象都是內置對象。

舉例說明一下:

// 普通對象就是普通對象嘍
let ordinary_obj = {
  a: 'test',
  b: 1
}
// 怪異對象就是非普通對象,例如函數的參數args、數組對象、字符串對象等
let standard_object = new String('lalala')
// 標準對象就是本規範定義的例如
let standard_obj = new Array()
// 內置對象就是宿主環境內置的對象例如
let built_in_obj = console
複製代碼

這些不過重要,就不細說了(由於我也不太懂😂)

本規範章節組織

第五章:規範的記法約定。

第六-九章:定義了ES程序運行的執行環境。

第十-十六章:定義了實際的ES程序語言,包括句法編碼、運行時語義等。

第十七-二十六章:定義了ES標準庫,包括ES程序執行時可用的全部標準對象。

第二十七章:描述了SharedArrayBuffer支持的內存訪問的內存一致性模型以及Atomics對象的方法。

記法約定

這章主要是一些編譯原理的知識。不作過多探討,有興趣能夠看🔗

語法和詞法

上下文無關法

上下文無關文法由多個產生式(production)組成.每一個產生式具備做爲其左側的非終結符號以及右側零個或多個非終結符號和終結符,對於每一個語法,終端符號從指定的字母表中繪製。

鏈產生式(chain production)是在其右側具備一個非終端符號以及零個或多個終端符號的產生式。

從由單個區分的非終止符(稱爲目標符號)組成的句子開始,給定的上下文無關語法規定了語言,便可能的 能夠由右側序列中的任何非終端,重複替換非終止符是左側的終端符號的序列。

來舉個:chestnut::

ArrayLiteral: ​ [Elision]

​ [ElementList]

​ [ElementList, Elision] ElementList:Elision AssignmentExpression

Elision SpreadElement

ElementList, Elision AssignmentExpression

ElementList, Elision SpreadElement Elision: ​ ,

Elision , SpreadElement: ​ ...AssignmentExpression

上面是定義數組字面量的產生式(省略了不少參數,加上參數後使得語法更加完備)🔗。其中斜體字就是非終結符,意味着還能夠再往下推導;非斜體字就是終結符,意味着不能再推導了。

從上自下,ArrayLiteral表明一個數組字面量,其有三種可能的表示方式,這三種又能夠往下推直到不能再推導爲止。

例如[]就屬於[Elision],[1,2]就屬於[ElementList]。

這樣的描述覆蓋了全部ES裏的數組字面量的語法形式。

算法約定

在描述ES語言語義時,使用了一些算法步驟,你們能夠將其看做僞代碼。

很簡單的(假的😂,有些我也不太懂,不敢亂講。不過不影響理解運行時語義,因此也很少說了。)


這篇就完了,感受沒講啥,好多我不關心的都沒講,有點慚愧。😂

下一篇就正式開始接觸ES了,講講ES的數據類型和值(包括語言的和規範的)還有一些基本的抽象操做(用於描述ES的語義)。

相關文章
相關標籤/搜索