前言
ECMAScript 2015(ES6)新增內容很多,在 ES5 發佈近 6 年(2009-11 至 2015-6)之後纔將其標準化。兩個發佈版本之間時間跨度如此之大主要有兩大原因:
- 比新版率先完成的特性,必須等待新版的完成才能發佈。
- 那些需要花長時間完成的特性,也頂着很大的壓力被納入這一版本,因爲如果推遲到下一版本發佈意味着又要等很久,這種特性也會推遲新的發佈版本。
因此,從 ECMAScript 2016(ES7)開始,版本發佈將會變得更加頻繁,每年發佈一個新版本,這麼一來新增內容也會更小。新版本將會包含每年截止時間之前完成的所有特性。
如何設計ECMAScript
TC39(推進 JavaScript 發展的委員會) 設計過程
每個 ECMAScript 特性的建議將會從階段 0 開始, 然後經過下列幾個成熟階段。其中從一個階段到下一個階段必須經過 TC39 的批准。
階段 0: Strawman 初稿
什麼是 Strawman?
一個推進 ECMAScript 發展的自由形式的想法。該想法必須由 TC39 的會員提交,如果是非會員則必須註冊成爲 TC39 貢獻者才能提交。
必備條件:
文件必須在 TC39 的會議上通過審議(原文),然後才能加入階段 0 的建議頁面。
什麼是 Draft?草案是規範的第一個版本。其與最終標準中包含的特性不會有太大差別。
必備條件:建議此時必須要附加該特性的語法和語義的正式說明(使用 ECMAScript 標準的形式語言)。說明應該儘可能完善,但可以包含待辦事項和佔位符。該特性需要兩個實驗性的實現,其中一個可以在類似 Babel 的轉譯器(transpiler)中實現。
下一步:從該階段開始只接受增量調整。
階段 3:Candidate 候選
什麼是 Candidate?候選階段,建議基本完成,此時將從實現過程和用戶使用兩方面獲取反饋來進一步完善建議。
必備條件:規範文檔必須是完整的。指定的評審人(由 TC39 而不是帶頭人指定)和 ECMAScript 規範的編輯須在規範上簽字。還有至少要兩個符合規範的實現(不必指定默認實現)。
下一步:此後,只有在實現和使用過程中出現了重大問題纔會修改建議。
階段 4:Finished 完成
什麼是 Finished?建議已經準備就緒,可以添加到標準之中。
必備條件:建議進入完成階段之前需要滿足以下幾點:
- Test 262 的驗收測試(基本上都是 JavaScript 寫的用來驗證語言特性的單元測試)。
- 兩個通過測試的符合規範的實現。
- 特性實現相關的重要實踐經驗。
- ECMAScript 規範的編輯在規範文本上的簽字。
下一步: 建議將會盡快加入 ECMAScript 規範之中。當規範通過年度審覈成爲標準,該建議也正式成爲標準的一部分。
ECMAScript 2016新增特性
已被納入 ES2016 的特性
- Array.prototype.includes
- 指數運算符
1、Array.prototype.includes
Array.prototype.includes方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes方法類似
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
如果傳入的值在當前數組(this)中則返回 true,否則返回 false
includes方法與 indexOf 方法很相似 下面兩個表達式是等價的:
arr.includes(x)
arr.indexOf(x) >= 0
唯一的區別是 includes() 方法能找到 NaN,而 indexOf() 不行:
[NaN].includes(NaN)
true
[NaN].indexOf(NaN)
-1
includes 不會區分 +0 和 -0(這也與其他 JavaScript 特性表現一致):
[-0].includes(+0)
true
- 爲什麼方法取名
includes
而不是contains
? 後者是最初的選擇,但在 web 上將會破壞已有的代碼(MooTools 在Array.prototype
上添加了 contains 方法)。 - 爲什麼方法取名
includes
而不是has
? has 通常用於鍵(Map.prototype.has),includes 通常用於元素(String.prototype.includes)。集合中的元素既可以被看當做 鍵 也可被當做 值,所以纔有 Set.prototype.has (而不是 includes)。 -
ES6 的
String.prototype.includes
方法可用於字符串,而不能用於字符。這是否和Array.prototype.includes
不一致? 如果數組和字符串的 includes 方法是相同的工作機制,那麼數組的 includes 方法就應該接受數組,而不是數組元素了。不過這兩個 includes 方法都參考了 indexOf 方法;字符一般是特殊情況,而任意長度的字符串則更常見。
2、指數運算符
新提出來的特性是將 ** 作爲指數操作的中綴運算符:
2 ** 2 // 4
2 ** 3 // 8
這個運算符的一個特點是右結合,而不是常見的左結合。多個指數運算符連用時,是從最右邊開始計算的。
// 相當於 2 ** (3 ** 2)
2 ** 3 ** 2
// 512
上面代碼中,首先計算的是第二個指數運算符,而不是第一個。
指數運算符可以與等號結合,形成一個新的賦值運算符(**=)。
let a = 1.5;
a **= 2;
// 等同於 a = a * a;
let b = 4;
b **= 3;
// 等同於 b = b * b * b;
注意,V8 引擎的指數運算符與Math.pow
的實現不相同,對於特別大的運算結果,兩者會有細微的差異。
99**99
3.697296376497268e+197
Math.pow(99,99)
3.697296376497263e+197