做者:Yann sjavascript
翻譯:瘋狂的技術宅前端
原文:medium.com/engineered-…java
未經容許嚴禁轉載node
**什麼是 JavaScript?**據 Wikipedia 的描述,它是一種符合 ECMAScript 規範的腳本語言。 ES6,ES7等這些名字你可能據說過,你也極可能已經使用 ES6 有一段時間了(在不少狀況下經過 Babel 使用)。react
我肯定大家中的大多數人都在使用許多不一樣的 ES6 新功能,而無需問本身:這真的是 ES6嗎,瀏覽器支持該功能嗎?不過你對 Babel 在 2019 年進行的轉換了解多少?你是否從新瞭解了 ES 中的內容?自從首次提出 ES6 提案以來,刪除了哪些內容?自最初的 ES7 提案以來又增長了什麼?webpack
讓咱們坐下來回顧一下 ES 的當前狀態。自 Babel 和 ES6 誕生以來都發生了什麼,什麼已徹底集成?git
我認爲讓你從新瞭解某項目的不一樣階段是頗有用的。es6
本質上,這些功能經歷了從 0 到 4 的階段,0 是最先的階段,而 4 是「準備發佈」。github
階段 0 是純屬有人提出的想法,將其整理爲階段 1 的提案,進行審查和討論,直到階段 3 爲止,最終將其劃分爲階段 4 的優先級。到達階段 4 後,將會在瀏覽器中實現並計劃發佈。web
在此處獲取全部 deets:tc39.es/process-doc…
簡而言之,ES6(或 ES2015)是根據 2015里程碑 經過了第4階段的一系列功能。換句話說,若是你對 ES6 有很好的理解,而且對 ES7 有必定的瞭解,那麼你大約有4年的時間能夠追趕……沒有壓力。
讓咱們看一下 ES6 的正式組成部分。順便說一下,全部這些功能在全部瀏覽器中都獲得正式支持。換句話說,無論你使用哪一個瀏覽器都不須要 Babel(除非你須要支持 IE 11)。
在 ES6 中,咱們可以獲得:
建立和繼承類的能力。
class MyComponent extends React.Components {}
複製代碼
具備導入和導出功能的ES6模塊。
import * from 'React';export default MyComponent;
複製代碼
生成器
let fibonacci = {
*[Symbol.iterator]() {
let pre = 0, cur = 1
for (;;) {
[ pre, cur ] = [ cur, pre + cur ]
yield cur
}
}
}
複製代碼
咱們還有:模板,箭頭函數,Promise,新的數字類型,Const/Let,類型化數組,數組解構,Map/Set,符號。
這裏是全部功能的列表:es6-features.org
你注意到了嗎?裝飾器,對象解構(例如 React
props:{…props}
)等都不屬於 ES6!
關於在 ES7(ES2016) 中,如下是咱們可以獲得的。這是一個很小的更新:
base ** exponent
array.includes(myItem) // true 或 false
資料來源: ecma-international.org/ecma-262/7.…
你可能已經注意到 Async/Await 不是 ES7 的一部分,而是屬於 ES8!
在過去的兩年中,每一個接受過 JavaScript 相關面試的人都被問到過 ES6 是什麼以及它帶來什麼功能。可是有人發現 JS 顯然並無忽然停留在 ES6 和 ES7 上,可是沒有人問你個嗎?這是你糾正問題的機會!
在 **ES8(ES2017)**中,如下是可用功能:
myString.padStart(2); // 或 padEnd
function test(a,b,c, ) // notice the coma after c
固然還有 Async/Await 函數:
async MyAjaxGetCall(url) {
return ajax.get(url)
}const response = await MyAjaxGetCall("/getUsers");
console.log(response) // response is available without using promise.then
複製代碼
若是你已經閱讀了這篇文章,那麼如今應該明白了:除少數例外,這些功能是 Stage 4,你能夠在沒有 Babel 的瀏覽器中使用它們(也就是說,ES8 是 ES2017,它仍然是最新的, Edge 和 Opera 之類的引擎對某些實現滯後了一點)。
如今轉到 ES9。就像 ES8 和 ES6 同樣,ES9(或ES2018)是一個至關重要的更新:
myNewObject = {a,b,c, …object}
大多數瀏覽器已經支持這些功能!
最後,轉到 ES10(或 ES2019)!
[[1,2],3]).flat() // [1,2,3]
map().flat()
Object.entries
的反向操做(參見此處)} catch {
而不是 } catch(e){
)Function.toString
的行爲一致性的問題🥳🥳🥳const array = [
{key: 2, value: 'd'},
{key: 1, value: 'a'},
{key: 1, value: 'b'},
{key: 1, value: 'c'},
];
array.sort(...)
/* [ {key: 1, value: 'a'}, {key: 1, value: 'b'}, {key: 1, value: 'c'}, {key: 2, value: 'd'}, ] */
複製代碼
若是 ES6 是 ES2015,而 ES7 是 ES2016,你能猜出 ES5 屬於哪一年嗎?
…你輸了! (除非你真的知道,但由於我聽不到你的聲音,因此我假設你錯了)。 ES5 是 ES2009!
在 ES5 以前,最後一次 ES 更新是在 1999 年!
如你所見,從 97 到 99 更新很是頻繁,在以後的 16 年裏,ES5 是惟一的更新!
咱們如何解釋呢?好吧,我認爲這有兩個因素。
第一個是技術上的:「JavaScript 很爛」。老實說,確實如此。那時,咱們有一些 JS 的替代品:Java Applets,ActiveX 甚至 Flash。
直到 2011 年以前,不只這些技術比 JS 快好幾個數量級, 並且它們還具備咱們仍在爲 JS 努力爭取的不少功能。 (Java 具備全部的語言功能,例如類和裝飾器,支持多線程,OpenGL,套接字等)。當 Chrome 和 Google 入場後並在 2013 年宣佈淘汰 Java(而後是 Flash)時,JS 遇上其競爭對手的征戰已經開始。兩年後,咱們有了ES6。
第二個因素是經濟上的:2000 年是互聯網泡沫爆發的一年。對於大家中最小的孩子,想像一下幾年前的比特幣,互聯網初創公司在 90 年代後期是同樣的。初創公司爲了得到大量的風險投資在名稱的末尾添加了 .com(就像如今的 mySuperStartup**.ai** 同樣),直到其價值在 20 年代忽然降低。這是一個很是基本的解釋,請你看一下 wikipedia 上文章來得到更詳細的解釋。
關鍵是,Internet 再也不得到使 JS 和與 Web 相關的技術成爲焦點所需的吸引力。後來隨着 Amazon、Facebook 和 Google 的興起,Web 有了新的發展理由,咱們選擇 JS 是合乎邏輯的! Chrome 於2008 年發佈,並在 2014 年成爲最受歡迎的瀏覽器:這是 ES6 發行的第一年。
這是一份從未進入第 4 階段提案的詳盡列表。你能夠在此處閱讀更多信息:github.com/tc39/propos…
最初它容許 JS 觀察代碼中的值:
var obj = {
foo: 0,
bar: 1
};
Object.observe(obj, function(changes) {
console.log(changes);
});obj.baz = 2;
// [{name: 'baz', object: <obj>, type: 'add'}]
複製代碼
這是一個很棒的功能,很明顯你能夠經過代碼(或 polyfill)來實現它,可是在瀏覽器中實現它的前提是實現更快的響應保證(例如:Angular 使用了大量觀察者)。之因此撤銷,是由於他們沒法實現穩定性能。 此處有更多詳細信息。
不言而喻,我敢確定,這並非惟一缺乏的功能。這個想法容許開發人員隨時取消任何 Promise 的執行。
用例會有所不一樣,例如,在異步操做時使客戶端超時,或者,若是你有一個選項卡驅動的導航系統,而且用戶在加載當前選項卡的內容以前單擊了另外一個選項卡。
我之因此僅說起這一點,是由於我喜歡它的名字,也由於它是一個與 Go Routines 或 C# Tasks 相似的出色功能。
const blöck = await {|
// This code is Async, but most importantly, executed in another thread
|};
複製代碼
還有一些有趣的建議,例如可調用的構造函數。其中大多數要麼因爲原始做者的緣由而被撤回,要麼由於與現有計劃中的特徵衝突或重疊而被拒絕。
目前,階段 0 ~ 3 中有一些使人興奮的東西。我會強調一些:
Observe 已被拒絕,但戰鬥並無中止,Observable 是一項改進 API 的提案,旨在消除 Observe() 遇到的性能瓶頸。
使用 Await 要求你處於異步函數內,這意味着你不能簡單地刪除包含 await 的腳本標籤,這不必定有意義,而且限制了 ES6 模塊在瀏覽器中無縫運行。它還容許你執行 fetch 操做或者不執行操做。
// You can do this in a .js file:
fetch(...).then((res) => something = res);
// But you can't do this unless you have a Async keyword
const res = await fetch(...);
複製代碼
也稱爲貓王(Elvis)運算符(我就是要這樣稱呼它,你沒法阻止我!),可以讓你輕鬆瀏覽對象而不會引起錯誤:
const test = myObject && myObject.a;
// equivalent to
const test = myObject?.a;
複製代碼
之因此稱爲貓王(Elvis)運算符,是由於運算符 ?: 看起來像貓王的側臉。
該提案還提到了 Nullish 合併運算符:
let x = 0 || 1; // x is 1 because 0 is falsy
let x = 0 ?? 1; // Since 0 is defined, x is 0
複製代碼
好長!能夠確定的是,你記不住全部內容,坦白地說,我也記不住!但願本文對你有一個全面的概述,並鼓勵你從新考慮對 JavaScript 的見解!我想從最多見的問題開始解答:
很好的問題!考慮到 JS(ES6 至 ES9)的最多見功能,已經徹底在除了 IE11 以外的瀏覽器中實現。你可能會認爲:「那麼,這還不夠好」。是的,還不夠好,由於你作出了選擇,因此你應該考慮:
在我撰寫本文時,目前 IE11 的瀏覽器佔有率爲 1.86%。可是不支持 IE11 並不意味着你會失去 1.86% 的受衆羣體,由於你應該考慮到人們可以切換瀏覽器,並且你的目標受衆羣體實際使用 IE11 的比例可能要低得多人員(例如:若是你定位的是年輕人)或技術愛好者)。
與不支持 IE11 所失去的金錢相比,支持 IE11 是否會給你帶來更多的收入?爲 IE11 開發不僅是使用 Babel。你還須要在該瀏覽器上測試全部功能,由於即便用了 Babel,其中一些功能也會受到損壞,而後找到全部這些問題的修復程序。間接費用可能不值得。
一樣,使用原聲函數比 Babel 的已編譯代碼的速度最多可提升3倍,正如這個基準測試所強調的那樣:www.inovex.de/blog/node-j… Babel 還會增長包的大小,最後,在開發時會增長構建時間。因此爲何要在每一個項目中都使用 Babel 呢!
與使用原生函數相比,Babel 下降了代碼執行速度,增長了包大小,並增長了構建時間。你真的在每一個項目中都須要它嗎?
你可能想知道爲何 JS 引入 let 而不是改進現有的 var關鍵字。答案很簡單:這樣作是爲了保持向後兼容性。你不想破壞 web,對吧? (我是認真的!)
Typescript 的規則是第 3 階段的提案。
Github 和官方網站在這裏: