也许你听说过Fetch API?基于promise对象的Web API,主要可以在浏览器发出网络请求,并且是开发人员的最爱。
如果复制
作为Web开发人员,我们总是被要求兼容所有或大部分主流浏览器。更多的用户也意味着更多的流量,更好的用户体验。因此,我们当然希望所有人都可以访问我们的web页面。问题是,我们的用户爸爸,总有一部分使用的旧的或特殊的浏览器。当不支持这些新功能时,我们作为开发人员都迫切需要Polyfill来拯救世界!
什么是polyfill?
Polyfill或者Polyfiller,是英国Web开发者 Remy Sharp 在咖啡店蹲坑的时候拍脑袋造出来的。当时他想用一个词来形容"用JavaScript来实现一些浏览器不支持的原生API"。Shim这个已经有的词汇第一时间出现在他的脑海里。但是他回头想了一下Shim一般有自己的API,而不是单纯实现原生不支持的API。苦思冥想一直想不到合适的单词,于是他一怒之下造了一个单词Polyfill。除了他自己用这个词以外,他还给其他开发者用。随着他在各种Web会议演讲和他写的书《Introducing HTML5》中频繁提到这个词,大家用了都觉得很好,就一起来用。
(左图为polyfill-软垫片,右图为shim-硬垫片)
Polyfill的准确意思为:磨平浏览器的缝隙,实现浏览器不支持的原生API的代码。
比如在具体项目中,兼容ie8以及ie8以下一直是一个难题,因为最常用的ES5的API却有很多都无法使用,比如getElementByClassName无法使用,querySelectorAll在ie8虽然可以使用,但也只能使用css2.1的选择器,诸如此类的问题有很多。
为了在日常开发中,开发者不会针对这种兼容性问题伤透脑筋,所出现的库就可以称为Polyfill。一个Polyfill是抹平新老浏览器 标准原生API 之间的差距的一种封装,而不是实现自己的API。
Polymer(低版本浏览器兼容html5 components)
FlashCanvas(兼容不支持canvas的浏览器)
polyfill的使用
如果你的代码运行的浏览器不支持想要使用JavaScript的功能(例如Object.assign()或fetch(),则通常的做法是(去github上找一个插件)写一段代码,打通这个API。这些代码称为polyfills,运行之后可以无感知的使用最新的API,不需要费尽心机考虑兼容。
这是MDN建议的polyfill的示例Number.isInteger():
Number.isInteger = Number.isInteger || function(value) {
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
};
只需将其添加到js代码中,并在使用它之前确保它已声明且在可及的范围内,那么就可以无感知的使用它了。
在NPM上也可以找到许多polyfill,例如babel-polyfill。合理的使用polyfill能够减轻开发者很大程度的工作量。
但是如何知道是否支持某个功能?
- 建议使用Mozilla开发人员网络的MDN Web文档。除了显示浏览器兼容性之外,它还包含出色的文档和经常建议使用的polyfill。
- CanIUse是一个更好的选择,它提供了一种快速简便的方法来查找Javascript,CSS等中许多不同功能的兼容性。
两种方式都可以选择,最好在canIuse查一次后,再去mdn再看一眼,但有些时候兼容性不一定全面,针对特殊浏览器,可以使用真机具体测试一下兼容性环境。
Polyfill通常与转译混淆。这两种技术解决了不同的问题。虽然polyfill会添加一些缺少的代码,但是转译可以转换代码,并使你能够编写某些浏览器可能不支持的语法,例如装饰器以及Class的声明方式。
我们什么时候可以不用polyfills?
只要有来自不同公司的多种主要浏览器以自己的方式运行,就无法保证它们能够与最新的标准(例如ECMAScript和WHATWG)保持一致。
但是,近年来对polyfill的需求主要与Internet Explorer中不受支持的功能有关。Internet Explorer的市场份额正在缓慢而稳定地下降,但据说在Windows 10的整个生命周期中都受到支持。好消息是,微软计划发布基于Google Chrome开源引擎的全新Edge Chromium,明年1月15日。我们希望Windows用户比上一个版本更快地采用此版本的Edge,以便像这样的错误消息时代可以终结。
参考文献
https://segmentfault.com/a/1190000002593432
https://javascript.christmas/2019/21"
我的github