JavaScript的迅速演变给Js开发者带来了更多的便利,同时也遇到了问题。对于Js开发者来说,我们非常想要使用这些新特性,但同时又被担心旧版浏览器不支持新版本特性,比如IE浏览器。是否要等到所有浏览器都支持新版本特性之后才开始在代码中使用这些新的API和语法呢,所有负责语言发展的人士都希望,新的特性和模式一旦在标准中稳定下来,并且浏览器能够实现他们之后,就能够在开发者的代码中得到应用。

怎么解决浏览器不支持新版语法和API的矛盾呢,答案就是: 工具化。利用一种transpiling(transformation+compiling,转换+编译)技术,用专门的工具把ES6代码转化为等价(或近似)的可以在ES5环境下工作的代码。

举例来说,有如下箭头函数:

(() =>{
	console.log('this is an arrow function')
})()

在不支持ES6语法的环境下是会报错的:

es6兼容插件 es6的兼容性_es6语法转换

通过transpiling转换之后的代码如下:

"use strict";

(function () {
  console.log('this is an arrow function');
})();

编程了一个ES5支持的IIFE函数,以上代码在不支持ES6的浏览器环境运行时没有问题的。这就是transpiling的原理了。怎样实现以上的转换呢?

Babel

Babel 是一个 JavaScript 编译器(https://www.babeljs.cn/docs/)。它是实现transpiling的一种方式,能够在代码构建阶段,将ES6(以及以上版本)中的语法转换为ES5形式,并实现基本一致的功能。以gulp构建工具为例,使用方式如下:

1.安装
 

# Babel 7
$ npm install --save-dev gulp-babel @babel/core @babel/preset-env

# Babel 6
$ npm install --save-dev gulp-babel@7 babel-core babel-preset-env

2.使用

新建gulpfile.js文件(需安装gulp),内容如下:

var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task('default',function(){
	gulp.src('test.js')
		.pipe(babel({
			presets:['@babel/env']
		}))
		.pipe(gulp.dest('dist'));
	
})

3.运行

命令行运行

H:\babel-complete-byNpm>gulp

运行完成之后,文件夹的dist下回多个test.js文件,打开文件之后就是babel转换之后的文件。

shim/polyfill

以上的babel只能转换ES6中的新语法,并不能转换新的API,比如数组的新方法includes。要想使用新版的API,还要进行 polyfill(也称为 shim)这种模式的转换。在可能的情况下,polyfill 会为新环境中的行为定义在旧环境中的等价行为。语法不能
polyfill,而 API 通常可以。

举例来说, Object.is(..) 是一个用于检查两个值严格相等的新工具,而且不像 === 那样在处理 NaN 和 -0 值的时候有微妙的例外情况。对 Object.is(..) 应用 polyfill 非常简单:

if (!Object.is) {
    Object.is = function(v1, v2) {
        // 检查-0
        if (v1 === 0 && v2 === 0) {
            return 1 / v1 === 1 / v2;
        }
        // 检查NaN
        if (v1 !== v1) {
            return v2 !== v2;
        }
        // 其余所有情况
        return v1 === v2;
    };
}

注意这个 polyfill 外层用于保护的 if 语句。这个细节很重要,它表示这段代码只定义了在未定义 API 的旧环境下的行为;需要覆盖已经存在的 API 的情况是非常罕见的。

使用方式:

1.安装

npm install --save babel-polyfill

因为这是一个 polyfill (它需要在你的源代码之前运行),我们需要让它成为一个 dependency,而不是一个 devDependency

2.在 Node / Browserify / Webpack 中使用

你需要在你的应用入口顶部通过 require 将 polyfill 引入进来。确保它在任何其他代码/依赖声明之前被调用!

require("babel-polyfill");

如果你在你的应用入口使用 ES6 的 import 语法,你需要在入口顶部通过 import 将 polyfill 引入,以确保它能够最先加载:

import "babel-polyfill";

webpack.config.js 中,将 babel-polyfill 加到你的 entry 数组中:

module.exports = {
  entry: ["babel-polyfill", "./app/js"]
};

 这里有一组名为“ES6 Shim”的 ES6 shim 实现(https:// github.com/paulmillr/es6-shim/),你一定要把它作为一个标准放在你所有的 JavaScript 新项目中。人们认为 JavaScript 会持续不断地发展,浏览器会逐渐地而不是以大规模突变的形式支持新特性。所以,保持 JavaScript 发展更新的最好战略就是在你的代码中引入 polyfill shim,并且在构建过程中加入 transpiler 步骤,现在就开始接受并习惯这个新现实吧。
如果还要保持现状,等着所有浏览器都支持某个特性才开始应用这个特性,那么你就已经落后了。你将遗憾地错过所有设计用于使得编写 JavaSript 更高效健壮的创新。