1. Introduction

Recently, while studying Babel, I came across the concept of polyfill. Although I have heard of shim and polyfill, I have been confused about the difference between these two academic terms. Google comes up with a lot of material, but most of it is long and obscure or copied. So I found a Shim library and a Polyfill library respectively. Es6-shim and ES6-Promise. Links to both libraries will be placed at the end of the article. Now look at the code for both libraries to see how shim’s functionality is defined differently from Polyfill’s.

2.shim

Analyzed the es6-SHIm source code, now the overall logic is combed into the following code:

// UMD
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(factory);
  } else if (typeof exports === 'object') {
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.returnExports = factory();
  }
}(this.function () {
  'use strict';
  // Determine and get the global object
  var getGlobal = function () {
    if (typeofself ! = ='undefined') { return self; }
    if (typeof window! = ='undefined') { return window; }
    if (typeofglobal ! = ='undefined') { return global; }
    throw new Error('unable to locate global object');
  }
  // Get the global object in the environment
  var globals = getGlobal();
  // es6 Map
  globals.Map = ...
  // es6 Set
  globals.Set = ...
  // es6 Symbol
  globals.Symbol = ...
  
  When the ES6-Shim library is introduced, the global object API is automatically mounted on the global object, i.e. a new environment is created.
  return globals
}))
Copy the code

Note: When the SHIm library is introduced, it affects global objects. Create a new environment by adding apis to global objects. Shim does not determine whether the API already exists.

3.polyfill

Polyfill code logic for ES6-Promise:

import Promise from './promise';

export default function polyfill() {
  let local;
  // Use the same UMD here
  if (typeofglobal ! = ='undefined') {
    local = global;
  } else if (typeofself ! = ='undefined') {
    local = self;
  } else {
    try {
      local = Function('return this') (); }catch (e) {
      throw new Error('polyfill failed because global object is unavailable in this environment'); }}let P = local.Promise;
    // This checks whether the global object has a Promise property.
  if (P) {
    var promiseToString = null;
    try {
      promiseToString = Object.prototype.toString.call(P.resolve());
    } catch(e) {
      ...
    }
    if (promiseToString === '[object Promise]' && !P.cast){
        // If you already have a Promise, return it directly without adding the Promise attribute to the global object.
      return; }}// The code executes here, adding the Promise API to the global object
  local.Promise = Promise;
}
Copy the code

Note: From the above source, it can be seen that Polyfill library and shim library roughly the same logic. The difference, however, is that Polyfill determines whether the current environment already has the target API, stops if it does, and only adds the API implemented by Polyfill when it does not.

3. Summary

From the analysis and comparison above, you can see that Shim is for the environment and Polyfill is for the API.

When shim is used, it doesn’t care if the old environment already has an API, it simply rechanges the global object to provide an API for the old environment (it is a shim that provides new functionality for the old environment, thus creating a new environment).

In Polyfill, it determines if an API already exists in the old environment and adds a new ONE if it doesn’t (it’s putty, smoothing out the API differences between different environments).

The goals are not the same.

4. Source code link

es6-shim

es6-promise