ECMAScript 6 简介

120 阅读6分钟

ECMAScript 6 是 JavaScript 语言的下一代标准,已于 2015 年 6 月正式发布。它的目标是使 JavaScript 语言可以用于编写复杂的大型应用程序,成为企业级开发语言

ECMAScript 和 JavaScript 的关系

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现

ES6 和 ECMAScript 2015 的关系

2011 年,ECMAScript 5.1 版本发布后,6.0 版本便开始制定。因此,ES6 这个词的愿意就是指,JavaScript 语言的下一个版本

ES6 的第一个版本是在 2015 年 6 月正式发布的。正式名称为《ECMAScript 2015 标准》

ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版本以后得 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等

语法提案的批准流程

一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准

  • Stage 0,展示阶段
  • Stage 1,征求意见阶段
  • Stage 2,草案阶段
  • Stage 3,候选阶段
  • Stage 4,定案阶段

一个提案只要进入 Stage2 ,就基本认为其会包括在以后得正式标准里面

ECMAScript 的历史

  • ECMAScript 1.0 是 1997 年发布的
  • ECMAScript 2.0 是 1998 年 6 月发布
  • ECMAScript 3.0 是 1999 年 12 月发布
    • 3.0 版本奠定了 JavaScript 语言的基本语法,被其后的版本完全继承
  • 2000 年,ECMAScript 4.0 开始酝酿
    • 但这个版本最后没有通过,但其大部分内容被 ES6 所继承,因此 ES6 制定的起点其实是在 2000 年
    • 4.0 版本没有通过,是因为这个版本太激进,对 ES3 做了彻底升级,导致标准委员会的一些成员不愿意接受

ECMA 的第 39 号技术专家委员会(简称 TC39)负责制定 ECMAScript 标准,成员包括 Microsoft、Mozilla、Google 等大公司

  • 2009 年 12 月,ECMAScript 5.0 正式发布
  • 2011 年 6 月,ECMAScript 5.1 发布,并且成为 ISO 国际标准
  • 2013 年 3 月,ECMAScript 6 草案冻结,不再添加新功能
  • 2013 年 12 月,ECMAScript 6 草案通过
  • 2015 年 6 月,ECMAScript 6 正式通过,成为国际标准

部署进度

使用如下命令,可以查看 Node 中已经实现的 ES6 特性

node --v8-options | grep harmony

Babel 转码器

Babel 是一个广为使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在浏览器或其它环境执行

配置文件 .bebelrc

Babel 的配置文件是 .babelrc,存放在项目的根目录下

该文件用来设置转码规则和插件,基本格式如下

{
    "presets": [],
    "plugins": []
}

presets 字段设定转码规则,官方提供一下的规则集,可以根据需要进行安装

# 最新转码规则
npm install --save-dev babel-preset-latest

# react 转码规则
npm install --save-dev babel-preset-react

# 不同阶段语法提案的转码规则(共有 4 个阶段),选装一个
npm install --save-dev babel-preset-stage-0
npm install --save-dev babel-preset-stage-1
npm install --save-dev babel-preset-stage-2
npm install --save-dev babel-preset-stage-3

然后,将这些规则加入 .babelrc 中

{
    "presets": [
        "latest",
        "react",
        "stage-2"
    ],
    "plugins": []
}

命令行转码 babel-cli

Babel 提供 babel-cli 工具,用于命令行转码

安装命令

npm install --global babel-cli

基本用法

# 转码结果输出到标准输出
babel example.js

# 转码结果写入一个文件
# --out-file 或 -o 参数执行输出文件
babel example.js --out-file compiled.js

# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
babel src --out-dir lib

# -s 参数生成 source map 文件
babel src -d lib -s

babel-node

babel-cli 工具自带一个 babel-node 命令,提供一个支持 ES6 的 REPL 环境,可以直接运行 ES6 代码

执行 babel-node 可以进入 REPL 环境

babel-node
> (x => x * 2)(1)
2

babel-register

babel-register 模块改写了 require 命令,为它加上一个钩子。此后,每当使用 require 加载后缀为 .js、.jsx、.es 和 .es6 的文件时,就会先用 Babel 进行转码

npm install --save-dev babel-register

在使用时,必须首先加载 babel-register,这样就不需要手动对 index.js 进行转码了

require('babel-register')
require('./index.js')

babel-core

如果某些代码需要调用 Babel 的 API 进行转码,就要用到 Babel-core 模块

npm install babel-core --save

在项目中调用

var babel = require('babel-core')

// 字符串转码
babel.transform('code();', options)
// => { code, map, ast }

// 文件转码(异步)
babel.transformFile('filename.js', options, function(err, result) {
    result; // => { code, map, ast }
})

// 文件转码 (同步)
babel.transformFileSync('filename.js', options)
// => { code, map, ast }

// Babel AST 转码
babel.transformFromAst(ast, code, options)
// => { code, map, ast }

关于 options 的内容,可以参考官方文档,babeljs.io/docs/usage/options/

var es6Code = 'let x = n => n + 1'

var es5Code = require('babel-core').transform(es6Code, {
    presets: ['latest']
}).code

// '"use strict";\n\nvar x = function x(n) {\n  return n + 1;\n};'

babel-polyfill

Babel 默认只转换新的 JavaScript 句法,而不转换新的 API,以及一些定义在全局对象上的方法,都不会转码

如果想让这些方法运行,必须使用 babel-polyfill 为当前环境提供一个垫片

npm install --save babel-polyfill
import 'babel-polyfill'

// 或者

require('babel-polyfill')

浏览器环境

Babel 也可以用于浏览器环境,但是,从 Babel 6.0 开始将不再直接提供浏览器版本,而是要用构建工具构建出来。如果没有或不想使用构建工具,可以使用 babel-standalone 模块提供的浏览器版本,将其插入网页

以下命令将代码打包成浏览器可以使用的脚本,以 Babel 配合 Browserify 为例。首先安装 babelify 模块

npm instal --save-dev babelify babel-preset-latest

然后,再用命令行转换 ES6 脚本

browserify script.js -o bundle.js \ -t [ babelify --presets [ latest ] ]

将 ES6 脚本 script.js 转为 bunlde.js,浏览器直接加载后者即可

在 package.json 中添加下面的代码,则不必每次都输出参数

{
    "browserify": {
        "transform": [["babelify", { "presets": ["latest"] }]]
    }
}

与其它工具的配合

许多工具需要 Babel 进行前置转码,如 ESLint 和 Mocha

ESLint 用于静态检查代码的语法和风格

npm install --save-dev eslint babel-eslint

在项目根目录下新建一个配置文件 .eslintrc,在其中加入 parser 字段

{
    "parser": "babel-eslint",
    "rules": {
        ……
    }
}

Mocha 是一个测试框架,如果需要执行使用 ES6 语法的测试脚本,可以将 package.json 的 scripts.test 修改如下

"scripts": {
    "test": "mocha --ui qunit --compilers js:babel-core/register"
}

上面命令中, --compilers 参数指定脚本的转换器,规定后缀为 .js 的文件都要使用 babel-core/register 先进行转码