JS: polyfill vs. shim vs. transpiler
先來看一下MDN對於polyfill的定義:
A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.
Polyfill是由Remy Sharp所創造的名詞,廣義來說polyfill主要是在模擬該環境原生未實作的API行為的程式碼(但此API可能在其他環境有實作),另外過去也用來弭平不同瀏覽器要以不同實作去實現相同功能的問題(MDN)。
以前端舉例來說,是指在舊瀏覽器模擬一些新瀏覽器才有的功能,假設舊瀏覽器沒有提供Number.isNaN()可以加入以下程式碼polyfill類似Number.isNaN()的行為:
// 這只是簡單演示,實際上不會這樣實作。
if (!Number.isNaN) {
Number.isNaN = function isNaN(x) {
return x !== x;
};
}
補充一下,前述定義會這樣寫的有點模糊是因為Remy Sharp認為有些情況下也需要「polyfill」新瀏覽器(譬如在最新版的IE瀏覽器模擬同期其他瀏覽器才有的API?)
不過Remy Sharp當時也是用IE瀏覽器舉例解釋polyfill,譬如IE8已經提供sessionStorage API,polyfill(或稱polyfiller)即是提供IE7或更早以前版本一些模擬sessionStorage功能的API。
另外,在polyfill一詞出現以前,有個叫shim的名詞,但polyfill和shim不同的地方在於,shim是指「實現環境原生尚未提供的API」,也就是自己去補足環境目前任何版本都沒有的功能。
最後還有一個常與polyfill出現的名詞「transpiler」:
A transpiler is a special piece of software that translates source code to another source code. It can parse (“read and understand”) modern code and rewrite it using older syntax constructs
transpiler字面上的意思指的是用其他程式碼替換既有程式碼,可能只是語法上的替換,並無牽涉任何新功能的實作。以JavaScript和瀏覽器來說,可透過transpiler以ES5語法替換掉舊版瀏覽器可能看不懂的ES6語法,譬如某些瀏覽器未支援ES6的箭頭函式(arrow function)語法,transpiler就會將箭頭函式替換成函式宣告式(function declaration)等ES5以前支援、幾乎具備同等功能的函式語法。
References