昨天在瀏覽 Babel 網站時,看到它的 blog 有一篇新的文章,說 Babel 發佈了新的代碼支持 class 的私有屬性和方法。javascript
這着實讓我頭腦混亂,到底在哪能夠了解到最新的規範?而這些規範又是否被支持?支持到什麼程度?徹底沒有頭緒。html
自從 ES6 規範發佈以來,帶來不少新的特性,而咱們在消化這些大量的知識時,ES 規範也在不停的調整和增長內容。但是咱們沒有一個特定的流程和渠道來獲取最新的資訊,這反而會愈來愈落後於前沿技術。java
因此在2018年的年底我整理了一下學習 ES 特性的流程和過程當中要接觸到的名詞。git
在20世紀60隨着計算機的普及,不一樣製造商在使用各自的標準開發軟件,這使得爲這些不一樣的設備編寫語言更加困難。es6
爲了統一計算機領域的部分標準,歐洲知名的計算機制造商們決定城裏一個協會來組建並制定章程和規則,這個協會就是「歐洲計算機制造協會」(European Computer Manufacturers Association) 簡稱「ECMA」github
時間到了1994年,爲了體現全球化的進程,該協會更名爲「歐洲信息和通訊系統標準化協會」(European association for standardizing information and communication systems) 簡稱 「Ecma International」,雖然名稱變化了,可是由於某些歷史緣由「Ecma」的商標卻任然保留了下來沿用至今。正則表達式
Ecma 的歷史算法
「TC39」全稱「Technical Committee 39」譯爲「第39號技術委員會」,是 Ecma 組織架構中的一部分。是負責迭代和發展 ECMAScript 語言規範的委員會,它的成員由各個主流瀏覽器廠商的表明組成,一般每一年召開約 6 次會議來討論未決提案的進展狀況,會議的每一項決議必須獲得大部分人的贊同,而且沒有人強烈反對才能夠經過。編程
TC39 主要負責:數組
ECMAScript 從 ES5 版本到 ES6 版本的發佈經歷了6年的時間,這帶來了兩個問題:
- 即便很早就完成的某項特性,也必須等到整個版本發佈才能發佈出來。
- 有些特性的定製會花費不少時間,那麼它在實現前都必須承受很大的壓力,由於沒有遇上本次發佈就必須再等好久,直至下一次發佈。
所以 TC39 改變了過去漫長的發佈流程,從 ECMAScript 2016 (ES7) 開始,每一年發佈一個版本,這個版本會包含本年完成的全部功能。
那什麼功能算是完成,又有什麼功能能夠加入議程中呢?
這就須要瞭解一下 TC39 的工做流程,TC39 會收集各類提案,這些提案來自 TC39 會員或註冊爲 TC39 撰稿人的非會員。而提案會從 0 階段(stage 0)開始進入審覈流程,它們最終會演變爲 ECMAScript 的標準,或者被廢棄。後面的章節中會詳細介紹。
ECMAScript 是一種計算機語言的規範,是 Ecma 組織的第 262 號規範(Ecma-262)。
如今咱們也用 ESx 來指代 ECMAScript x 版本(x 表明六、201六、2017等)。
Javascript 是 ECMAScript 的一個實現。之因此用這麼奇怪的方式來描述它,是由於任何人或組織均可以依照規範來實現語言。舉例來講,微軟也曾經按照 ECMAScript 標準開發出一門語言叫作 JScript,這門語言本用在 IE 瀏覽器中。
不過在普世語境下 Javascript 和 ECMAScript 兩個詞已經可互換使用了,而它們也確實有很深的羈絆。
1996年8月,微軟模仿 JavaScript 開發了一種相近的語言,取名爲JScript(JavaScript 是 網景 的註冊商標,微軟不能用),首先內置於IE 3.0。網景公司面臨喪失瀏覽器腳本語言的主導權的局面。網景公司決定將 JavaScript 提交給 Ecma,但願 JavaScript 可以成爲國際標準,以此抵抗微軟。
在提交給 Ecma 之因此不叫 JavaScript,一方面是因爲商標的關係,Java 是 Sun 公司的商標,根據一份受權協議,只有網景公司能夠合法地使用 JavaScript 這個名字,且 JavaScript 已經被網景公司註冊爲商標,另外一方面也是想體現這門語言的制定者是 Ecma,不是網景,這樣有利於保證這門語言的開放性和中立性。
ECMAScript® 2018 Language Specification
JavaScript 語言的歷史 - JavaScript 教程 - 網道
What is language and what is dialect for computers?
1997年 Ecma 發佈 「ECMAScript Language Specification, Edition 1」簡稱「ES1」,隨後的每次發佈都會在原有版本上加1。
2009年 ES5正式發佈,而兩年後 ES5.1發佈。
又過了6年,一拖再拖的 ES6 才問世。
人們已經察覺到 Javascript 的發展速度要比其規範要快得多,一旦一個想法進入討論階段,瀏覽器就會嘗試爲這個特性開發原型,而社區也會開始編碼實驗。
因此有人建議將來的版本應該基於年份,好比用 ES2016 來標示在 2016 年結束以前敲定的任何特性規範。
儘管 ES6 被正式改名爲 ES2015,但人們仍是更多的習慣稱其爲 ES6。不過從 ES6 之後的規範版本就正式使用年份的命名方式。
額外說一句,尚未正式發佈的規範也就是還在定製階段的特性都被稱爲 ESNext。
What is ESNext? Is it same as ECMAScript? - Web, Design, Programming
以前說到 TC39 會收集各類提案,並讓這些提案進入審覈流程,一步步推動。整個流程有5個階段,每一個階段都有必定的准入門檻和評定標準,咱們也不須要關心這些標準條目,咱們只須要知道一個提案到達的階段越靠後則它被歸入規範的可能性就越大。
stage-0 - 稻草人(straw-man) 基本沒有準入門檻,合規的想法均可以進入這個階段。
stage-1 - 提案(proposal) 須要肯定一個提案推動人。而後歸納問題或需求而且造成一個解決方案,列舉新提案使用的方法或提供的API。討論關鍵算法、概念和語義。
stage-2 - 草案(Draft) 這個階段須要使用正式的規範語言精確地描述語法和語義
stage-3 - 候選方案(Candidate) 當草案進入這個階段就須要進一步細化並接收用戶的反饋,並描述完全部語義、語法和 API。
stage-4 - 結束(Finished) 當進入這個階段時,提案會接受測試和驗收,經過後就會進入下一個版本 ES 規範的標準之中。
每一年7月份,TC39 會正式發佈當年的 ES 規範。
The TC39 process for ECMAScript features
很高興 ECMAScript 擁抱了 GitHub 社區,經過社區自己的力量來發展自身並回饋於社區。
TC39 擁有不少倉庫:
因此迴歸到章節的問題上來,咱們要追蹤 ES6 之後的規範變化就須要在 proposals 倉庫裏找答案。這個倉庫包含了 4 大部分,分別是 「stage-0 的提案列表」、「stage-1 到 3 的提案列表」、「結束(stage-4)的提案列表」和「非活躍(inactive)的提案列表」。
咱們在 結束的提案列表裏 能找到全部 ES6 之後添加的特性,下面就列出這些特性以及發佈的規範版本:
ES2016:
ES2017
ES2018
在「結束的提案列表裏」還包含了一些計劃在 2019 年發佈的特性,因爲其還未正式發佈我將其概括在 ESNext 中就不在此列出了。
Release ES2016 Draft 1 · tc39/ecma262 · GitHub
proposals/finished-proposals.md · tc39/proposals · GitHub
特性的演變迅速也讓 JavaScript 開發者遇到了問題,新的特性可使得編寫出更高效健壯的代碼,但咱們咱們的網站卻要支持未提供這些新特性的舊版瀏覽器。在功能特性快速進化的環境下這個問題更加嚴峻。
上圖中綠色的部分就是 ECMAScript 特性和瀏覽器支持的特性的差別部分,這個差別能夠分紅兩大部分:新的 API和新的語法。
新的 API 是在原有對象的拓展,好比
Array.includes
就是對數組對象的拓展。它一般是解決一些歷史遺留問題或者對經常使用代碼邏輯的封裝。
舉例來講,Object.is()
是一個用於檢查兩個值是否嚴格相等的新接口。===
在處理 NaN
和 -0
這樣的值時會有微妙的歧義,而 Object.is()
就是用來解決這樣問題的。
NaN === NaN; // false
Object.is(NaN, NaN) // true
複製代碼
對於 API 的擴展帶來的規範特性和瀏覽器特性的差別,一般都有一個被稱爲 polyfill 或者 shim 的模式來抹平。這兩個詞的意思分別是 膩子 和 墊片,從詞義上來講已經能很形象的描述它們的做用。
而 polyfill 可使用 ES5 的代碼來實現這些新 API,就以 Object.is()
來講就能夠用如下代碼來實現:
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}
複製代碼
新的語法就好比
let
,是對功能的擴展。想要在舊瀏覽器中使用不支持的語法就必需要使用「轉換+編譯」的技術,利用專門的工具把代碼轉化爲等價(或近似)的能夠在 ES5 環境下工做的代碼。
在後面的章節裏會介紹用 Babel 來編譯新的 ES 語法。
這裏提供一個網站,專門查看兼容性表格。包含瀏覽器、手機端和服務器端。
簡單介紹一下就是,在 某版本[1] 下的 某項特性[2] 在 某編譯器或瀏覽器[3] 中的 兼容程度[4]。
ECMAScript 6 compatibility table
Babel 是一個 JavaScript 編譯工具,專門用來編譯 ECMAScript 6+ 的代碼讓其兼容就瀏覽器或運行環境。它能夠轉換語法、補充 API。
在聖經故事裏,Babel 譯爲「巴別塔」,當時世界只講同一種語言,人類決定修建一座可以通天的高塔來傳播本身的名聲。上帝知道了此事,擔憂人類過於強大,就打亂了人類的語言,讓人類不講同語不齊同心。因而人類便分裂開來,這座塔也再也不建造了。
而這個編譯器借用 Babel 之名,彷佛是想幫助人類統一 Javascript 語言呢(笑。
鑑於它在社區的普及程度很高因此本文不會介紹其具體的使用方式,而是介紹它如何配合 TC39 的工做流程。
現在的 Babel 已經發展到第7個大版本,它提供的子功能的責任劃分也愈來愈清晰,對於開發者來講須要關心兩個方面:
- 把代碼編譯到什麼程度?
- Babel 對新 ES 特性的支持程度是多少?
一般把代碼編譯到 ES5 的版本是最安全的,這個版本已經獲得絕大多數瀏覽器的支持,但這會讓編譯後的代碼文件更大。但咱們總不能在2030年還這樣作,隨着舊瀏覽器逐漸被淘汰,咱們也不須要把全部的特性都編譯至 ES5 的版本。
Babel 本次更新的第7個版本,引入了 @babel/preset-env
來動態管理編譯程度。若是進入這個包而不作任何配置,則會默認把代碼編譯到 ES5 版本。
重要的是此次 @babel/preset-env
僅包含了對已正式發佈的 ES 規範的支持。若是要使用任一 stage-0 到 stage-3 中的特性或者 stage-4 中存在可是當年還未正式發佈的特性,就必須安裝相應的插件。
若是新特性以API的方式實現,就須要在polyfill中查看,polyfill中包含一個core-js列表專門包含了這些API。
GitHub - zloirock/core-js: Standard Library
這就是本文的最終總結了,怎樣嘗試使用一個新的特性。
若是你在別人的代碼裏或者網絡上發現一個你沒見過的 JS 代碼語法你應該怎麼辦呢?
首先你應該嘗試經過搜索引擎找到這種語法的正式名稱。而後你就能夠去 TC39 的 github 中找一下,你能夠在 ecma-262 正式文檔中找(不過這個文檔太長了)也能夠在 proposals 列表裏找一下,別遺漏了 finished proposals 和 inactive proposales 列表,最終你就會找到這個語法的介紹和用例。
接着你會想看一下這個語法在不一樣環境下的支持程度,因此你須要打開兼容性表格查詢頁面查找這個語法。
接着你也許會想嘗試着編寫一個用例並運行一下,那你須要在 Babel 的官網裏查一下 plugins 列表裏是否支持該語法,若是是新的 API 那就須要在 core-js 列表裏找一下。
接着你就能夠配置好 Babel 並編寫用例,編譯成瀏覽器兼容的代碼,在瀏覽器裏運行了。
TC39 on GitHub - TC39 的 GitHub 賬號
ECMAScript® Language Specification - ECMAScript 最新修訂版(當年準備發佈的文檔)
ECMAScript® Language Specification - ECMAScript 最新正式版(已發佈的最新文檔)
proposals - 提案列表
ECMAScript 6 compatibility table - 兼容性表格查詢頁面
@babel/Plugins · Babel - Babel 支持的語法插件列表
GitHub - zloirock/core-js - Babel polyfill 中支持的 API 列表
Exploring JS - 在線學習 JS 的網站做者挺牛的
ES.next News - ES 新聞訂閱
寫於2019年1月。
若是喜歡文章 請留下一個贊~ 若是喜歡文章 分享給更多人~
自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證) 轉載時請保留原文連接 以保證可及時獲取對文章的訂正和修改