Javascript Polyfill 和轉(zhuǎn)譯器

2023-02-17 10:38 更新

JavaScript 語言在穩(wěn)步發(fā)展。也會(huì)定期出現(xiàn)一些對(duì)語言的新提議,它們會(huì)被分析討論,如果認(rèn)為有價(jià)值,就會(huì)被加入到 https://tc39.github.io/ecma262/ 的列表中,然后被加到 規(guī)范 中。

JavaScript 引擎背后的團(tuán)隊(duì)關(guān)于首先要實(shí)現(xiàn)什么有著他們自己想法。他們可能會(huì)決定執(zhí)行草案中的建議,并推遲已經(jīng)在規(guī)范中的內(nèi)容,因?yàn)樗鼈儾惶腥せ蛘唠y以實(shí)現(xiàn)。

因此,一個(gè) JavaScript 引擎只能實(shí)現(xiàn)標(biāo)準(zhǔn)中的一部分是很常見的情況。

查看語言特性的當(dāng)前支持狀態(tài)的一個(gè)很好的頁面是 https://kangax.github.io/compat-table/es6/(它很大,我們現(xiàn)在還有很多東西要學(xué))。

作為程序員,我們希望使用最新的特性。好東西越多越好!

另一方面,如何讓我們現(xiàn)代的代碼在還不支持最新特性的舊引擎上工作?

有兩個(gè)工作可以做到這一點(diǎn):

  1. 轉(zhuǎn)譯器(Transpilers)。
  2. 墊片(Polyfills)。

通過本文,我們一起了解它們的工作原理以及它們在 Web 開發(fā)中的位置。

轉(zhuǎn)譯器(Transpilers)

轉(zhuǎn)譯器 是一種可以將源碼轉(zhuǎn)譯成另一種源碼的特殊的軟件。它可以解析(“閱讀和理解”)現(xiàn)代代碼,并使用舊的語法結(jié)構(gòu)對(duì)其進(jìn)行重寫,進(jìn)而使其也可以在舊的引擎中工作。

例如,在 ES2020 之前沒有“空值合并運(yùn)算符” ??。所以,如果訪問者使用過時(shí)了的瀏覽器訪問我們的網(wǎng)頁,那么該瀏覽器可能就不明白 height = height ?? 100 這段代碼的含義。

轉(zhuǎn)譯器會(huì)分析我們的代碼,并將 height ?? 100 重寫為 (height !== undefined && height !== null) ? height : 100

// 在運(yùn)行轉(zhuǎn)譯器之前
height = height ?? 100;

// 在運(yùn)行轉(zhuǎn)譯器之后
height = (height !== undefined && height !== null) ? height : 100;

現(xiàn)在,重寫了的代碼適用于更舊版本的 JavaScript 引擎。

通常,開發(fā)者會(huì)在自己的計(jì)算機(jī)上運(yùn)行轉(zhuǎn)譯器,然后將轉(zhuǎn)譯后的代碼部署到服務(wù)器。

說到名字,Babel 是最著名的轉(zhuǎn)譯器之一。

現(xiàn)代項(xiàng)目構(gòu)建系統(tǒng),例如 webpack,提供了在每次代碼更改時(shí)自動(dòng)運(yùn)行轉(zhuǎn)譯器的方法,因此很容易將代碼轉(zhuǎn)譯集成到開發(fā)過程中。

墊片(Polyfills)

新的語言特性可能不僅包括語法結(jié)構(gòu)和運(yùn)算符,還可能包括內(nèi)建函數(shù)。

例如,?Math.trunc(n)? 是一個(gè)“截?cái)唷睌?shù)字小數(shù)部分的函數(shù),例如 ?Math.trunc(1.23)? 返回 ?1?。

在一些(非常過時(shí)的)JavaScript 引擎中沒有 ?Math.trunc? 函數(shù),所以這樣的代碼會(huì)執(zhí)行失敗。

由于我們談?wù)摰氖切潞瘮?shù),而不是語法更改,因此無需在此處轉(zhuǎn)譯任何內(nèi)容。我們只需要聲明缺失的函數(shù)。

更新/添加新函數(shù)的腳本被稱為“polyfill”。它“填補(bǔ)”了空白并添加了缺失的實(shí)現(xiàn)。

對(duì)于這種特殊情況,?Math.trunc? 的 polyfill 是一個(gè)實(shí)現(xiàn)它的腳本,如下所示:

if (!Math.trunc) { // 如果沒有這個(gè)函數(shù)
  // 實(shí)現(xiàn)它
  Math.trunc = function(number) {
    // Math.ceil 和 Math.floor 甚至存在于上古年代的 JavaScript 引擎中
    // 在本教程的后續(xù)章節(jié)中會(huì)講到它們
    return number < 0 ? Math.ceil(number) : Math.floor(number);
  };
}

JavaScript 是一種高度動(dòng)態(tài)的語言。腳本可以添加/修改任何函數(shù),甚至包括內(nèi)建函數(shù)。

兩個(gè)有趣的 polyfill 庫:

  • core js 支持了很多特性,允許只包含需要的特性。
  • polyfill.io 提供帶有 polyfill 的腳本的服務(wù),具體取決于特性和用戶的瀏覽器。

總結(jié)

在本章中,我們希望激勵(lì)你學(xué)習(xí)現(xiàn)代甚至“前沿”的語言特性,即使 JavaScript 引擎還沒有很好地支持它們。

只是不要忘記使用轉(zhuǎn)譯器(如果使用現(xiàn)代語法或運(yùn)算符)和 polyfill(添加可能缺少的特性)。它們將確保代碼能正常工作。

例如,以后熟悉了 JavaScript,你就可以搭建一個(gè)基于 webpack 和 babel-loader 插件的代碼構(gòu)建系統(tǒng)。

展示對(duì)各種特征的當(dāng)前支持情況的工具:

P.S. 谷歌的 Chrome 瀏覽器通常是對(duì)最新的語言特性的支持情況最好的瀏覽器,如果教程的示例運(yùn)行失敗,請嘗試使用 Chrome 瀏覽器。不過,教程中的大多數(shù)示例都適用于任意的現(xiàn)代瀏覽器。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)