什么是JavaScript?根據(jù)Wikipedia的說法,它是一種符合ECMAScript規(guī)范的腳本語言。ES6,ES7等…您可能聽說過這些名稱,您很可能已經(jīng)使用ES6一段時(shí)間了(在很多情況下是使用Babel的)。
我確定你們中的大多數(shù)人都在使用許多其他有趣的ES6功能,而不會(huì)問自己:這真的是ES6,瀏覽器是否仍不支持該功能?在您和我之間,您對(duì)Babel在2019年仍將進(jìn)行的轉(zhuǎn)換了解多少?您是否重新了解了ES中的內(nèi)容?自從首次提出ES6提案以來,刪除了哪些內(nèi)容?自最初的ES7提案以來增加了什么?
因?yàn)槲蚁嘈琶總€(gè)人都應(yīng)該關(guān)注何時(shí)最終在JS中獲得replaceAll函數(shù),所以讓我們坐下來回顧一下ES場(chǎng)景的當(dāng)前狀態(tài)。即將發(fā)生什么,自Babel和ES6誕生以來已經(jīng)完全整合了什么?
一點(diǎn)歷史和科學(xué)
讓我們回到過去!如果像我一樣,您在2014–2015年左右第一次聽說過ES6和Babel,您很可能仍然認(rèn)為事物在同一個(gè)地方或多或少在同一個(gè)地方。這很公平,因?yàn)槎嗵澚薆abel,我們只需要關(guān)心幕后的實(shí)際情況。但是正如您可能想像的那樣,Babel允許我們?cè)诋?dāng)時(shí)可用的“建議階段”功能在5年內(nèi)一直沒有保留“建議階段”功能。
為了使我在撰寫本文時(shí)停止用引號(hào)引起來的“建議階段”(在鍵入時(shí)很難用引號(hào)引起來),我認(rèn)為讓您重新了解某項(xiàng)目的不同階段是很有用的要合并的JS功能。
本質(zhì)上,這些功能經(jīng)歷了從0到4的階段,0是最早的階段,而4是“準(zhǔn)備發(fā)布”。

階段0是純屬有人提出的想法,將其整理為階段1的提案,進(jìn)行審查和討論,直到階段3為止,最后將其優(yōu)先級(jí)劃分為階段4。功能到達(dá)階段4后,便會(huì)在瀏覽器中實(shí)現(xiàn)并計(jì)劃發(fā)布。
在此處獲取所有說明
ES6和ES7-提醒
簡(jiǎn)而言之,ES6(或ES2015)是根據(jù)2015里程碑通過階段4的一批功能。換句話說,如果您對(duì)ES6有很好的了解,并且對(duì)ES7有一定的了解,那么您大約有4年的時(shí)間可以趕上……沒有壓力。
讓我們看一下ES6的正式組成部分。順便說一下,所有這些功能在瀏覽器中都得到正式支持。換句話說,您不需要Babel來使用它們中的任何一個(gè)(除非您支持IE 11)。
在ES6中,我們具有:
創(chuàng)建和繼承類的能力。
class MyComponent extends React.Components {
}
具有導(dǎo)入和導(dǎo)出功能的ES6模塊。
import * from 'React';
export default MyComponent;
Generators
let fibonacci = {
*[Symbol.iterator]() {
let pre = 0, cur = 1
for (;;) {
[ pre, cur ] = [ cur, pre + cur ]
yield cur
}
}
}
我們還提供:模板,箭頭函數(shù),Promise,新數(shù)字,Const / Let,類型化數(shù)組,數(shù)組解構(gòu),Map/Set,Symbols。此處所有功能的列表
你注意到了嗎?裝飾器,對(duì)象解構(gòu)(例如React props:{…props})等都不屬于ES6!
關(guān)于ES7(ES2016), 這就是我們擁有的。這是一個(gè)很小的更新:
-
冪運(yùn)算符
base ** exponent - 數(shù)組包含
array.includes(myItem) // true or false
您可能已經(jīng)注意到,Async / Await不是ES7的一部分,而是ES8!
ES8,ES9,ES10
在過去2年中,每個(gè)接受過JavaScript相關(guān)采訪的人都至少被問到1671次ES6是什么以及它帶來什么功能。但是有人發(fā)現(xiàn)JS顯然并沒有突然停在ES6和ES7上,但是,沒有人問你這件事嗎?這是您糾正問題的機(jī)會(huì)!
在ES8(ES2017)中,以下是可用功能:
- Object.entries / Object.values(數(shù)組的值/對(duì)象的鍵等效項(xiàng))
- 字符串填充
myString.padStart(2); // or padEnd - 尾隨逗號(hào)
function test(a,b,c, ) // notice the comma after c - 原子和共享內(nèi)存
當(dāng)然,Async / Await函數(shù):
async MyAjaxGetCall(url) {
return ajax.get(url)
}
const response = await MyAjaxGetCall("/getUsers");
console.log(response) // response is available without using promise.then
如果您已經(jīng)閱讀了這篇文章,那么現(xiàn)在您應(yīng)該明白了:除少數(shù)例外,這些功能是Stage 4,您可以在沒有Babel的瀏覽器中使用它們(也就是說,ES8是ES2017,它仍然是很新的, Edge和Opera的本機(jī)引擎之類的某些實(shí)現(xiàn)滯后了一點(diǎn))。

來到ES9。就像ES8和ES6一樣,ES9(或ES2018)是一個(gè)相當(dāng)重要的更新:
- 解除模板字面量限制(https://tc39.es/proposal-template-literal-revision/)?,F(xiàn)在,允許在模板中使用復(fù)雜的語法(例如:LaTex)
- 異步迭代器:可以將迭代器用于異步操作,例如讀取HTTP流(https://tc39.es/proposal-async-iteration/)以及引入for-wait-of
- Promise.finally:https : //github.com/tc39/proposal-promise-finally
- 對(duì)象解構(gòu)。是的!最后在這里,您已經(jīng)使用了很多年了,嗯,它是ES9的功能。非React開發(fā)人員的提醒:它允許您:myNewObject = {a,b,c,…object}
- 還包括unicode轉(zhuǎn)義和對(duì)Regexes的改進(jìn)

大多數(shù)瀏覽器已經(jīng)支持這些功能!
最后,來到ES10(或ES2019)!
- Array.flat:
[[1,2],3]).flat() // [1,2,3] - Array.flatMap:等同于map()。flat()
- Object.fromEntries:Object.entries的反向操作(請(qǐng)參閱此處)
- String.trimStart()和String.trimEnd():刪除字符串中的多余空格
- 可選的Catch綁定:無需在catch中添加參數(shù)(現(xiàn)在您可以
} catch {代替} catch(e) { - 已重新考慮Function.toString具有一致的行為??????
- symbol說明
- BigInt —任意大數(shù)(感謝@ redeyes2015進(jìn)行更正)
- 改進(jìn)了對(duì)JSON.stringify()的Unicode支持
- 現(xiàn)在,如果鍵相等,則Array.sort保留順序
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'},
]
*/
- 使JavaScript成為JSON的超集(此處的ee詳細(xì)信息)
那ES5呢?
如果ES6是ES2015,ES7是ES2016,您能猜出ES5是多少年?
ES5是ES2009!
在ES5之前,最新的ES更新是在1999年!

如您所見,從97到99,更新非常頻繁,然后ES5將成為16年內(nèi)唯一的更新!
我們?nèi)绾谓忉屇??好吧,我認(rèn)為這有兩個(gè)因素。第一個(gè)是技術(shù)性的:JavaScript很爛。老實(shí)說,確實(shí)如此。那時(shí),我們有一些JS替代品:Java Applets,ActiveX甚至Flash。
直到2011年代(Chrome開始成為子彈時(shí)代)時(shí),這些技術(shù)不僅比JS快了 一個(gè)數(shù)量級(jí),而且 它們還具有我們?nèi)缃袢栽谂Λ@得的JS的大多數(shù)功能。(Java具有所有語言功能,例如類和裝飾器,支持多線程,OpenGL,套接字等)。當(dāng)Chrome和Google進(jìn)入現(xiàn)場(chǎng)并在2013年宣布Java淘汰(然后是Flash)時(shí),促使JS趕上其競(jìng)爭(zhēng)對(duì)手的征戰(zhàn)正在進(jìn)行 。兩年后,我們有了ES6。
第二個(gè)因素是經(jīng)濟(jì)的:2000年是網(wǎng)絡(luò)泡沫破滅的一年。對(duì)于你們中最小的孩子,想像一下幾年前的比特幣,互聯(lián)網(wǎng)初創(chuàng)公司在90年代后期是一樣的。初創(chuàng)企業(yè)在名稱的末尾添加了.com,以獲得大量的風(fēng)險(xiǎn)投資(就像如今我們Promise的mySuperStartup .ai一樣),直到其價(jià)值在20年代突然下降。
關(guān)鍵是,Internet不再獲得使JS和與Web相關(guān)的技術(shù)成為焦點(diǎn)所需的吸引力。后來,隨著Amazon,F(xiàn)acebook和Google的興起,網(wǎng)絡(luò)有了一個(gè)新的理由,也有了一個(gè)蓬勃發(fā)展的新理由。我們選擇JS備份是合乎邏輯的!Google于2004年公開發(fā)布,Chrome于2008年發(fā)布,并在2014年成為最受歡迎的瀏覽器:比ES6發(fā)行早一年。
缺少了什么?(被拒絕的提案)
這是一份從未進(jìn)入階段4的提案的詳盡列表。您可以在此處閱讀更多信息:https : //github.com/tc39/proposals/blob/master/inactive-proposals.md
Object.observe
這可能是所有人中最大的拒絕。最初,它允許JS觀察代碼中的任何值:
var obj = {
foo: 0,
bar: 1
};
Object.observe(obj, function(changes) {
console.log(changes);
});
obj.baz = 2;
// [{name: 'baz', object: <obj>, type: 'add'}]
這是一個(gè)很棒的功能,很明顯,您可以通過代碼(或使用polyfill)來實(shí)現(xiàn)它,但是在瀏覽器中實(shí)現(xiàn)它是實(shí)現(xiàn)更快的響應(yīng)式代碼的保證(例如:Angular進(jìn)行了大量觀察)。之所以撤回是因?yàn)樗麄儫o法實(shí)現(xiàn)性能穩(wěn)定的實(shí)現(xiàn)。更多細(xì)節(jié)在這里。
可取消的Promise
不言而喻,我敢肯定,它并不是唯一缺少的一項(xiàng)功能。這個(gè)想法是允許開發(fā)人員在任何時(shí)候取消任何Promise的執(zhí)行。
用例會(huì)有所不同,例如在異步操作上使客戶端超時(shí),或者例如,如果您具有選項(xiàng)卡驅(qū)動(dòng)的導(dǎo)航系統(tǒng),并且用戶在有時(shí)間加載當(dāng)前選項(xiàng)卡的內(nèi)容之前先單擊了一個(gè)選項(xiàng)卡。
其他
還提出了其他一些有趣的建議,例如可調(diào)用的構(gòu)造函數(shù)。其中大多數(shù)要么由于原始作者的原因而被撤回,要么因與現(xiàn)有/計(jì)劃中的特征沖突或重疊而被拒絕。
下一步是什么?
目前,階段0–3中有一些令人興奮的事情。我以為我會(huì)強(qiáng)調(diào)一些:
可觀察的(階段0)
Observe被拒絕了,但是戰(zhàn)斗并沒有停止,Observable是一項(xiàng)旨在改進(jìn)API的建議,以消除Observe()遇到的性能瓶頸。
頂層等待(階段3)
使用Await要求您處于異步函數(shù)中,這意味著您不能簡(jiǎn)單地刪除其中包含await的腳本標(biāo)簽,這不一定有意義,并且是ES6模塊在瀏覽器中無縫運(yùn)行的限制。它還允許您執(zhí)行獲取操作以及不執(zhí)行操作。
// 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(...);
Optional 鏈接
可讓您輕松瀏覽對(duì)象而不會(huì)引發(fā)任何錯(cuò)誤:
const test = myObject && myObject.a;
// equivalent to
const test = myObject?.a;
之所以稱為Elvis運(yùn)算符,是因?yàn)閺膫?cè)面看原始的運(yùn)算符 ?: 看起來像Elvis。
該提案還提到了一個(gè)Nullish合并運(yùn)算符,我希望我們也能找到一個(gè)更好的名稱:
let x = 0 || 1; // x is 1 because 0 is falsy
let x = 0 ?? 1; // Since 0 is defined, x is 0
結(jié)論和常見問題解答
可以肯定的是,您將不會(huì)記住所有內(nèi)容,并且坦率地說,我也不會(huì)!希望這對(duì)您有一個(gè)很好的概述,并鼓勵(lì)您重新考慮對(duì)JavaScript的看法!我想從所有最重要的問題開始常見問題解答:
我還需要babel嗎?
很好的問題!考慮到JS(ES6至ES9)的最常見功能,除了IE11之外,還可以在瀏覽器中完全實(shí)現(xiàn)。您可能會(huì)認(rèn)為:“那么,這還不夠好”。但是答案還不夠好,并且因?yàn)槟龀隽诉x擇,所以您應(yīng)該考慮:
—在我撰寫本文時(shí),IE11目前占瀏覽器總數(shù)的1.86%。但是,不支持IE11并不意味著您會(huì)失去1.86%的受眾群體,因?yàn)槟鷳?yīng)該考慮到人們能夠切換瀏覽器,而且您的目標(biāo)受眾群體實(shí)際使用IE11的比例可能要低得多(例如:如果您定位的是年輕人)人員或技術(shù)愛好者)。
—與不支持IE11所失去的金錢相比,支持IE11是否會(huì)給您帶來更多的收入?為IE11開發(fā)不只是使用Babel。您還需要在該瀏覽器上測(cè)試所有功能,因?yàn)榧词故褂肂abel,其中某些功能也會(huì)損壞,然后找到所有這些問題的修復(fù)程序。間接費(fèi)用可能不值得。
同樣,使用本機(jī)函數(shù)而不是Babel的已編譯代碼的速度最高可提高3倍,如該基準(zhǔn)測(cè)試所強(qiáng)調(diào)的那樣:https : //www.inovex.de/blog/node-js-10/。Babel還會(huì)增加包的大小,最后,開發(fā)時(shí)會(huì)減慢構(gòu)建時(shí)間。因此,為什么要在每個(gè)項(xiàng)目中重新考慮使用Babel!
與使用本機(jī)函數(shù)相比,Babel減慢了代碼的速度,增加了包的大小并減慢了構(gòu)建時(shí)間。您真的在每個(gè)項(xiàng)目中都需要它嗎?
為什么要添加諸如let之類的新關(guān)鍵字而不是進(jìn)行更新?
您可能想知道為什么JS引入let而不是改進(jìn)現(xiàn)有的var關(guān)鍵字。答案很簡(jiǎn)單:這樣做是為了保持向后兼容性。您不想破壞網(wǎng)絡(luò),對(duì)嗎?(我的意思是……這次是真實(shí)的?。?/p>