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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章