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

## 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