在JavaScript中有兩個(gè)詞經(jīng)常被提到:shim和polyfill特漩。它們指的都是什么黔攒,又有什么區(qū)別?
shim
一個(gè)shim是一個(gè)庫匆赃,它將一系列新的师郑、標(biāo)準(zhǔn)的API引入到一個(gè)舊的環(huán)境中,而且僅靠舊環(huán)境中已有的手段實(shí)現(xiàn)舊版兼容漫蛔。
例如我們經(jīng)常聽到的es5-shim嗜愈,它是在es3的引擎上實(shí)現(xiàn)了es5的特性,但用到的都是es3的技術(shù)莽龟,而且在Node.js上和在瀏覽器上有完全相同的表現(xiàn)蠕嫁,所以它是shim。
polyfill
polyfill是解決跨瀏覽器API兼容性問題的shim毯盈,相當(dāng)于一段代碼剃毒。
我們通常的做法是先檢查當(dāng)前瀏覽器是否支持某個(gè)API,如果不支持的話就加載對應(yīng)的polyfill搂赋,然后新舊瀏覽器就都可以使用這個(gè)API了赘阀。
比較有趣的是,polyfill這個(gè)詞源于英國的填強(qiáng)面料脑奠,中文俗稱"膩?zhàn)?”基公,把舊的瀏覽器想象成為一面有了裂縫的墻,而膩?zhàn)涌梢园堰@面墻的裂縫抹平宋欺,還我們一個(gè)光滑的"瀏覽器"墻面轰豆。
Remy在自己2010年10月8日的博客中介紹了這個(gè)新詞的來源:What is a Polyfill?。
他給出的定義是:
A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively. Flattening the API landscape if you will.(一段代碼或插件迄靠,可以讓開發(fā)人員使用應(yīng)有的技術(shù)秒咨,就像瀏覽器原生提供該功能一樣。換句話說掌挚,它能幫你抹平API之墻雨席。)
文中也提到了Paul的定義:
A shim that mimics a future API providing fallback functionality to older browsers.(一種模仿未來API并為舊瀏覽器提供后備功能的“襯墊”)
怎樣區(qū)分polyfill和shim?
- 如果瀏覽器X支持標(biāo)準(zhǔn)規(guī)定的功能吠式,那么polyfill可以讓瀏覽器Y的行為與瀏覽器X一樣陡厘。
- 而前面所說的es5-shim在es3的引擎上實(shí)現(xiàn)了es5的特性,但用到的都是es3的技術(shù)特占,而且在Node.js上和在瀏覽器上有完全相同的表現(xiàn)糙置,所以它是shim。
比如是目,jQuery不是polyfill谤饭,但下面這段代碼是:
// 首先包含jQuery
if (!document.querySelectorAll) {
Element.prototype.querySelectorAll = function (q) {
return $(this).find(q).get();
};
// document對象不是Element對象的后代,因此手工重寫
document.querySelectorAll = Element.prototype.querySelectorAll;
}
參考資料: