JavaScript 語言在穩步發展。也會定期出現壹些對語言的新提議,它們會被分析討論,如果認爲有價值,就會被加入到 https://tc39.github.io/ecma262/ 的列表中,然後被加到 規範 中。
JavaScript 引擎背後的團隊關于首先要實現什麽有著他們自己想法。他們可能會決定執行草案中的建議,並推遲已經在規範中的內容,因爲它們不太有趣或者難以實現。
因此,壹個 JavaScript 引擎只能實現標准中的壹部分是很常見的情況。
查看語言特性的當前支持狀態的壹個很好的頁面是 https://compat-table.github.io/compat-table/es6/(它很大,我們現在還有很多東西要學)。
作爲程序員,我們希望使用最新的特性。好東西越多越好!
另壹方面,如何讓我們現代的代碼在還不支持最新特性的舊引擎上工作?
有兩個工作可以做到這壹點:
轉譯器(Transpilers)。
墊片(Polyfills)。
通過本文,我們壹起了解它們的工作原理以及它們在 Web 開發中的位置。
轉譯器 是壹種可以將源碼轉譯成另壹種源碼的特殊的軟件。它可以解析(“閱讀和理解”)現代代碼,並使用舊的語法結構對其進行重寫,進而使其也可以在舊的引擎中工作。
例如,在 ES2020 之前沒有“空值合並運算符” ??
。所以,如果訪問者使用過時了的浏覽器訪問我們的網頁,那麽該浏覽器可能就不明白 height = height ?? 100
這段代碼的含義。
轉譯器會分析我們的代碼,並將 height ?? 100
重寫爲 (height !== undefined && height !== null) ? height : 100
。
// 在運行轉譯器之前 height = height ?? 100; // 在運行轉譯器之後 height = (height !== undefined && height !== null) ? height : 100;
現在,重寫了的代碼適用于更舊版本的 JavaScript 引擎。
通常,開發者會在自己的計算機上運行轉譯器,然後將轉譯後的代碼部署到服務器。
說到名字,Babel 是最著名的轉譯器之壹。
現代項目構建系統,例如 webpack,提供了在每次代碼更改時自動運行轉譯器的方法,因此很容易將代碼轉譯集成到開發過程中。
新的語言特性可能不僅包括語法結構和運算符,還可能包括內建函數。
例如,Math.trunc(n)
是壹個“截斷”數字小數部分的函數,例如 Math.trunc(1.23)
返回 1
。
在壹些(非常過時的)JavaScript 引擎中沒有 Math.trunc
函數,所以這樣的代碼會執行失敗。
由于我們談論的是新函數,而不是語法更改,因此無需在此處轉譯任何內容。我們只需要聲明缺失的函數。
更新/添加新函數的腳本被稱爲“polyfill”。它“填補”了空白並添加了缺失的實現。
對于這種特殊情況,Math.trunc
的 polyfill 是壹個實現它的腳本,如下所示:
if (!Math.trunc) { // 如果沒有這個函數 // 實現它 Math.trunc = function(number) { // Math.ceil 和 Math.floor 甚至存在于上古年代的 JavaScript 引擎中 // 在本教程的後續章節中會講到它們 return number < 0 ? Math.ceil(number) : Math.floor(number); }; }
JavaScript 是壹種高度動態的語言。腳本可以添加/修改任何函數,甚至包括內建函數。
兩個有趣的 polyfill 庫:
core js 支持了很多特性,允許只包含需要的特性。
在本章中,我們希望激勵妳學習現代甚至“前沿”的語言特性,即使 JavaScript 引擎還沒有很好地支持它們。
只是不要忘記使用轉譯器(如果使用現代語法或運算符)和 polyfill(添加可能缺少的特性)。它們將確保代碼能正常工作。
例如,以後熟悉了 JavaScript,妳就可以搭建壹個基于 webpack 和 babel-loader 插件的代碼構建系統。
展示對各種特征的當前支持情況的工具:
https://compat-table.github.io/compat-table/es6/ —— 對于原生 JavaScript。
https://caniuse.com/ —— 對于浏覽器相關的函數。
P.S. 谷歌的 Chrome 浏覽器通常是對最新的語言特性的支持情況最好的浏覽器,如果教程的示例運行失敗,請嘗試使用 Chrome 浏覽器。不過,教程中的大多數示例都適用于任意的現代浏覽器。