JavaScript中 polyfill 和 shim 的區別和聯繫

polyfill是什麼?

Polyfill是用在瀏覽器API上的shim。我們通常的做法是先檢查當前瀏覽器是否支持某個API,如果不支持的話就加載對應的polyfill。這樣新舊瀏覽器就都可以使用相同的API了。把舊的瀏覽器想象成爲一面有了裂縫的牆,這些polyfill(膩子)會幫助我們把這面牆的裂縫抹平。

polyfill 是 shim 的一種。一個polyfill可以是一段代碼(或者插件),提供了那些開發者們希望瀏覽器原生就支持的功能。主要撫平不同瀏覽器之間對js實現的差異。

shim是什麼?

shim 是將不同 API 封裝成一種的庫,shim將一個新的API引入到一箇舊的環境中,而且僅靠舊環境中已有的手段實現。

比如 jQuery是一個shim庫,jQuery 的 $.ajax方法 封裝了 XMLHttpRequest 方法和 IE 用 的ActiveXObject 方式來創建 xhr 對象(通俗地講,依靠瀏覽器原生支持的兩個API,封裝成$.ajax這個新的API,使用時,只需調用$.ajax這個新的API ,而不是調用XMLHttpRequest或ActiveXObject這兩個原生API )。

可以把shim,理解成能夠兼容之前版本的庫,是一種優雅降級。

polyfill 特指 shim 成的 api 是遵循瀏覽器標準的,其典型做法是在IE瀏覽器中增加window.XMLHttpRequest ,內部實現使用 ActiveXObject(見下面舉例)。

如何區分polyfill和shim?

舉例1

問題:舊版本的 IE 不支持標準的 XMLHttpRequest,但支持自家的 ActiveXObject 方法

解決辦法1-shim(jQuery中,把XMLHttpRequest和ActiveXObject這兩個新舊瀏覽器中的原生API,封裝成 $.ajax 這個新的API。使用時,只要熟悉 $.ajax這個新的API 的使用就可以了,不用考慮瀏覽器的兼容問題)

$.ajax = function(url) { 
  if (isIE) {
    XMLHttpRequest(url) 
  } else {
    ActiveXObject(url) 
  }
}

解決辦法2-polyfill(判斷瀏覽器  是否支持新版瀏覽器中XMLHttpRequest這個原生API,如果不支持,就用舊版瀏覽器中ActiveXObject這個原生API 來實現  一個功能跟  新版瀏覽器中XMLHttpRequest這個原生API   完全一樣的函數,並賦值給XMLHttpRequest這個原生API,這樣,開發者使用時,就還可以使用XMLHttpRequest這個原生API啦,不用再去學習jQuery庫咯)

if (!window.XMLHttpRequest) { 
  window.XMLHttpRequest = function(url) {
    ActiveXObject(url) 
  }
}

舉例2

問題:舊瀏覽器不支持 ES6 的 Array.prototype.find 方法

解決辦法1-shim(封裝一個新的API,使用時也調用這個新的API)

function arrayFind () { 
  if (Array.prototype.find) {
    // ... 
  } else {
    // ... 
  }
}

解決辦法2-polyfill(判斷瀏覽器  是否支持新版瀏覽器中Array.prototype.find這個原生API, 如果不支持,就實現一個函數,並賦值給Array.prototype.find這個原生API,這樣,開發者使用時,就還可以使用Array.prototype.find這個原生API啦)

if (!Array.prototype.find) { 
  Array.prototype.find = function() {
    // ... 
  }
} 

總結

以上舉例中,兩種解決辦法都能解決跨瀏覽器兼容的問題,看着也沒有特別的差別。

但是我們更推薦【解決辦法2】,

首先,像shim這樣應用一個新的API,有一定的學習成本,特別是在多人協作的過程中,如果你自己定義了一個方法去解決兼容問題,就需要告知其他開發人員這個新的API應該如何調用。而polyfill的做法,還是調用原生API就OK啦!

其次,polyfill可以實現按需加載,只在舊瀏覽器上加載兼容代碼。

與君共勉:再牛逼的夢想,也抵不住傻逼般的堅持!

發佈了84 篇原創文章 · 獲贊 64 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章