[TOC]
# 概括
[Respoke](http://blog.respoke.io/post/111278536998/javascript-shim-vs-polyfill) 创造了一个有趣的流程图,来决定一个特定的库是一个`shim`还是一个`polyfill`。他们之间的界限并不总是那么尖锐。试着回答下面的问题并作出决定:
1. 您的库是否在主要浏览器中修复了一些功能并且或者规范化了JavaScript API
2. JavaScript API是否存在于一些主流浏览器中?
3. 你的库是否实现了浏览器中不存在的JavaScript API
![shim or polyfill](https://box.kancloud.cn/647aea2405b788897d1ee6b1862b353a_447x624.png)
## polyfill
在2010年10月份的时候,Remy Sharp在博客上发表了一篇关于术语"[polyfill](http://remysharp.com/2010/10/08/what-is-a-polyfill/)"的文章,`polyfill`可以检测某个“预期”API是否缺失,如果没有就手动实现它,例如:
~~~
if (!Function.prototype.bind) { Function.prototype.bind = ...; }
~~~
## shim
`shim`是拦截现有API调用并实现不同行为的代码。有时候也称为 shiv,比如 [html5shiv](https://github.com/aFarkas/html5shiv) ,这里的想法是**在不同的环境中规范化某些api**。因此,如果两个浏览器实现了相同的 API,您就可以在其中一个浏览器中拦截 API 调用,并使其行为与其他浏览器保持一致。或者,如果一个浏览器在其 API 中有一个 bug,您可以再次拦截对该 API 的调用,然后绕过这个 bug。通常,`shim`用于向后兼容性。
# Polyfill.io
自动化的 JavaScript Polyfill 服务
Polyfill 可以为旧浏览器提供和标准 API 一样的功能。比如你想要 IE 浏览器实现 Promise 和 fetch 功能,你需要手动引入[es6-promise](https://github.com/stefanpenner/es6-promise)、[whatwg-fetch](https://github.com/github/fetch)。而通过[Polyfill.io](https://polyfill.io/),你只需要引入一个 JS 文件。
~~~html
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
~~~
Polyfill.io 通过分析请求头信息中的 UserAgent 实现自动加载浏览器所需的 polyfills。
Polyfill.io 有一份[默认功能列表](https://polyfill.io/v2/docs/features/#default-sets),包括了最常见的 polyfills:`document.querySelector`、`Element.classList`、ES5 新增的`Array`方法、`Date.now`、ES6 中的`Object.assign`、`Promise`等。
你也可以通过传递`features`参数来自定义功能列表:
~~~html
<!-- 加载 Promise&fetch -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise,fetch"></script>
<!-- 加载所有 ES5&ES6 新特性 -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es5,es6"></script>
~~~
Polyfill.io 还提供了其他 API,具体请查阅[官方文档](https://polyfill.io/v2/docs/api):
~~~html
<!-- 异步加载 -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?callback=main" async defer></script>
<!-- 无视 UA,始终加载 -->
<script src="https://cdn.polyfill.io/v2/polyfill.js?features=modernizr:es5array|always"></script>
~~~
[cdn.polyfill.io](http://cdn.polyfill.io/)使用 Fastly 提供的 CDN 服务,虽然没有中国节点,但测试下来速度也不慢,感兴趣的不妨试试这个服务~
# 参考
> [what-is-the-difference-between-a-shim-and-a-polyfill](https://stackoverflow.com/questions/6599815/what-is-the-difference-between-a-shim-and-a-polyfill/17331540#17331540)
> [Polyfill vs. Shim](https://blackat.github.io/2016/10/25/polyfill-vs-shim.html)
> [What is the difference between a shim and a polyfill?](http://2ality.com/2011/12/shim-vs-polyfill.html)
- 步入JavaScript的世界
- 二进制运算
- JavaScript 的版本是怎么回事?
- JavaScript和DOM的产生与发展
- DOM事件处理
- js的并行加载与顺序执行
- 正则表达式
- 当遇上this时
- Javascript中apply、call、bind
- JavaScript的编译过程与运行机制
- 执行上下文(Execution Context)
- javascript 作用域
- 分组中的函数表达式
- JS之constructor属性
- Javascript 按位取反运算符 (~)
- EvenLoop 事件循环
- 异步编程
- JavaScript的九个思维导图
- JavaScript奇淫技巧
- JavaScript:shim和polyfill
- ===值得关注的库===
- ==文章==
- JavaScript框架
- Angular 1.x
- 启动引导过程
- $scope作用域
- $q与promise
- ngRoute 和 ui-router
- 双向数据绑定
- 规范和性能优化
- 自定义指令
- Angular 事件
- lodash
- Test