[TOC]
# 概括
[Respoke](http://blog.respoke.io/post/111278536998/javascript-shim-vs-polyfill) 創(chuàng)造了一個(gè)有趣的流程圖,來決定一個(gè)特定的庫是一個(gè)`shim`還是一個(gè)`polyfill`。他們之間的界限并不總是那么尖銳。試著回答下面的問題并作出決定:
1. 您的庫是否在主要瀏覽器中修復(fù)了一些功能并且或者規(guī)范化了JavaScript API
2. JavaScript API是否存在于一些主流瀏覽器中?
3. 你的庫是否實(shí)現(xiàn)了瀏覽器中不存在的JavaScript API

## polyfill
在2010年10月份的時(shí)候,Remy Sharp在博客上發(fā)表了一篇關(guān)于術(shù)語"[polyfill](http://remysharp.com/2010/10/08/what-is-a-polyfill/)"的文章,`polyfill`可以檢測某個(gè)“預(yù)期”API是否缺失,如果沒有就手動實(shí)現(xiàn)它,例如:
~~~
if (!Function.prototype.bind) { Function.prototype.bind = ...; }
~~~
## shim
`shim`是攔截現(xiàn)有API調(diào)用并實(shí)現(xiàn)不同行為的代碼。有時(shí)候也稱為 shiv,比如 [html5shiv](https://github.com/aFarkas/html5shiv) ,這里的想法是**在不同的環(huán)境中規(guī)范化某些api**。因此,如果兩個(gè)瀏覽器實(shí)現(xiàn)了相同的 API,您就可以在其中一個(gè)瀏覽器中攔截 API 調(diào)用,并使其行為與其他瀏覽器保持一致?;蛘?,如果一個(gè)瀏覽器在其 API 中有一個(gè) bug,您可以再次攔截對該 API 的調(diào)用,然后繞過這個(gè) bug。通常,`shim`用于向后兼容性。
# Polyfill.io
自動化的 JavaScript Polyfill 服務(wù)
Polyfill 可以為舊瀏覽器提供和標(biāo)準(zhǔn) API 一樣的功能。比如你想要 IE 瀏覽器實(shí)現(xiàn) Promise 和 fetch 功能,你需要手動引入[es6-promise](https://github.com/stefanpenner/es6-promise)、[whatwg-fetch](https://github.com/github/fetch)。而通過[Polyfill.io](https://polyfill.io/),你只需要引入一個(gè) JS 文件。
~~~html
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
~~~
Polyfill.io 通過分析請求頭信息中的 UserAgent 實(shí)現(xiàn)自動加載瀏覽器所需的 polyfills。
Polyfill.io 有一份[默認(rèn)功能列表](https://polyfill.io/v2/docs/features/#default-sets),包括了最常見的 polyfills:`document.querySelector`、`Element.classList`、ES5 新增的`Array`方法、`Date.now`、ES6 中的`Object.assign`、`Promise`等。
你也可以通過傳遞`features`參數(shù)來自定義功能列表:
~~~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 服務(wù),雖然沒有中國節(jié)點(diǎn),但測試下來速度也不慢,感興趣的不妨試試這個(gè)服務(wù)~
# 參考
> [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的世界
- 二進(jìn)制運(yùn)算
- JavaScript 的版本是怎么回事?
- JavaScript和DOM的產(chǎn)生與發(fā)展
- DOM事件處理
- js的并行加載與順序執(zhí)行
- 正則表達(dá)式
- 當(dāng)遇上this時(shí)
- Javascript中apply、call、bind
- JavaScript的編譯過程與運(yùn)行機(jī)制
- 執(zhí)行上下文(Execution Context)
- javascript 作用域
- 分組中的函數(shù)表達(dá)式
- JS之constructor屬性
- Javascript 按位取反運(yùn)算符 (~)
- EvenLoop 事件循環(huán)
- 異步編程
- JavaScript的九個(gè)思維導(dǎo)圖
- JavaScript奇淫技巧
- JavaScript:shim和polyfill
- ===值得關(guān)注的庫===
- ==文章==
- JavaScript框架
- Angular 1.x
- 啟動引導(dǎo)過程
- $scope作用域
- $q與promise
- ngRoute 和 ui-router
- 雙向數(shù)據(jù)綁定
- 規(guī)范和性能優(yōu)化
- 自定義指令
- Angular 事件
- lodash
- Test
