polyfill、ponyfill、prollyfill傻傻分不清楚

这篇文章发布于 2021年08月8日,星期日,14:52,归类于 Web综合。 阅读 4161 次, 今日 69 次 6 条评论

 

马儿素描

一、ponyfill是什么?

偶然进入谷歌实验室的Browser-FS-Access项目,这个项目使用 File System Access API 实现文件上传现在,对于不支持文件系统访问API的浏览器使用 <input type="file"><a download> 进行优雅降级。

这不是重点,重点是我在如此官方的项目中又一次见到了这个名字——ponyfill!

ponyfill填充

之前也见到过几次,以为是乡野名词,技术梗,坊间笑谈,没想到谷歌官方项目都这可这个名词,那就必须要搞清楚ponyfill是个什么东东了。

小马填充

关于ponyfill还有个专门的github项目,专门解释ponyfill是什么,以及和polyfill的区别。

polyfill字面意思是使用聚合物进行填充,有补窟窿的意味在里面,就好像有四面墙,有一面墙有个窟窿,使用东西把这个窟窿补上,让四面墙看起来一样,整整齐齐的就是polyfill。

整整齐齐一家人

ponyfill和polyfill类似,但是更纯净,无污染,就像小马一样,我称之为“小马填充”。

小马吃草

同样是让修补墙壁,ponyfill的策略则是另起炉灶,不会在原有的墙壁上修补,而是重新建一面墙,保证原来的墙壁还是那么原始纯净无污染。

二、polyfill和ponyfill的区别

举个例子,Array.isArray()方法可以判断一个对象是不是数组,此方法IE8浏览器并不支持。

如果采用 polyfill 策略,则代码会是下面这样:

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

采用和原生浏览器一样的API。

如果采用 ponyfill 策略,则代码会是下面这样:

function isArray (arg) {
  return Object.prototype.toString.call(arg) === '[object Array]';
}

使用示意:

isArray([]) // 返回 true

同样是让所有浏览器支持某功能,但是,并不会采用和规范一致的API。

也就是Ponyfill总是避免使用原生 API。

什么时候使用Ponyfill?

polyfill策略大部分时候都是很OK的,使用方便快捷,不需要关心各种细节。

但是,并不是所有的时候都适合使用polyfill。

  1. 有些原生API完全没法模拟,此时只能使用Ponyfill策略。例如本文一开始提到的 File System Access API,低版本浏览器完全搞不定。

    又例如 indexDB 能力,history.pushState()方法等,IE9浏览器根本没法模拟,只能使用 Ponyfill策略。

  2. 有些原生API规范还没稳定,或者处于快速迭代中,或者是浏览器部分支持,此时走polyfill策略可能会有问题,影响未来策略。例如自定义元素v1规范和v2规范。
  3. 有时候可能会通过对象存在与否判断浏览器,polyfill可能会影响逻辑。例如有业务代码使用 if (![].map) {} 判断是不是低版本IE浏览器,如果不小心引入了包含 Array.prototype.map 的代码,可能会出现问题。

其他

基本上,为了避免全局命名的污染,Ponyfill都是建议采用独立的模块化的方式开发与调用的,例如:

module.exports = function (arg) {
  return Object.prototype.toString.call(arg) === '[object Array]';
};
var isArray= require('is-array-ponyfill');
// 返回 true
isArray([]);

随着浏览器开始原生支持 export/import 模块导入导出,ponyfill 方法开始使用浏览器标准模块规范使用了:

export default function (arg) {
  return Object.prototype.toString.call(arg) === '[object Array]';
};
import isArray from 'is-array-ponyfill';
// 返回 true
isArray([]);

三、prollyfill又是什么鬼?

什么鬼? 查找相关资料的时候,发现还有个 prollyfill,搞笑了,prollyfill概念貌似还未加入正统,处于小范围转播阶段。

Prollyfill本质上就是 Polyfill,只是Polyfill的这个API还没有成为标准API,但是已经约定俗称,或者呼声很高,或者官方已经开始考虑,也就是你知道以后会有这个API,但是目前浏览器都还没有支持的API的实现。

例如 JSON.saveJSON.load 这两个未来可能的JSON方法

对了,还有个 Nottifill

Nottifill表示浏览器或Node环境以后可能支持的功能,但是,没有任何草案显示,细节实现和描述都是开发人员自己定义的。

例如,10年前 jQuery中的 remove() 方法,append()方法就有这种味道在里面。

四、结束语

上了年纪,心态稳了,内容也平静多了。

要是年轻的时候,肯定不会称“小马填充”,而会称“马化腾填充”,保证记忆深刻,数年都不会忘记。

就这吧,不多扯了,今天事儿太多了,本周计划估计完不成了。

欢迎分享,欢迎传播,让更多人知道这几个概念。

对了,下周我会在微博和掘金(关注我的沸点)上进行新书的抽奖,大家可以关注下,应该都是周一发(如果我忘记了那就是周二):

我的新书

感谢大家长久以来的支持,祝大家好运!

(本篇完)

分享到:


发表评论(目前6 条评论)

  1. Jacano说道:

    请问「什么时候使用Ponyfill?」的第一点
    Polyfill不能模拟的Ponyfill就能模拟吗?如果能,是如何模拟的,可以有个例子?

    • 张 鑫旭说道:

      很多啊,任何 Element.prototype 扩展的 DOM API方法均不能在 IE8 浏览器中模拟,因为这是 DOM Level 2的标准,IE8无法在 所有 HTML 元素上扩展方法。
      HTML元素的dataset属性的赋值的能力就无法Polyfill,却很容易Ponyfill。
      一些新的语法,如for…in遍历,sync/await,import/export等只能模拟,无法Polyfill。

  2. Aaronlam说道:

    只知道 polyfill,没想到还有那么多叫法,每种叫法还有他的深层含义。

  3. nextc说道:

    新书已卖,正在看。

  4. 张大的小迷弟说道:

    前辈,css新世界啥时候开售呢?期待好久了嘿嘿