mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
590 lines
22 KiB
Markdown
590 lines
22 KiB
Markdown
# ECMAScript 6简介
|
||
|
||
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
|
||
|
||
## ECMAScript 和 JavaScript 的关系
|
||
|
||
一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?
|
||
|
||
要讲清楚这个问题,需要回顾历史。1996年11月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给国际标准化组织ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是1.0版。
|
||
|
||
该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。
|
||
|
||
因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)。日常场合,这两个词是可以互换的。
|
||
|
||
## ES6 与 ECMAScript 2015 的关系
|
||
|
||
ECMAScript 2015(简称 ES2015)这个词,也是经常可以看到的。它与 ES6 是什么关系呢?
|
||
|
||
2011年,ECMAScript 5.1版发布后,就开始制定6.0版了。因此,ES6 这个词的原意,就是指 JavaScript 语言的下一个版本。
|
||
|
||
但是,因为这个版本引入的语法功能太多,而且制定过程当中,还有很多组织和个人不断提交新功能。事情很快就变得清楚了,不可能在一个版本里面包括所有将要引入的功能。常规的做法是先发布6.0版,过一段时间再发6.1版,然后是6.2版、6.3版等等。
|
||
|
||
但是,标准的制定者不想这样做。他们想让标准的升级成为常规流程:任何人在任何时候,都可以向标准委员会提交新语法的提案,然后标准委员会每个月开一次会,评估这些提案是否可以接受,需要哪些改进。如果经过多次会议以后,一个提案足够成熟了,就可以正式进入标准了。这就是说,标准的版本升级成为了一个不断滚动的流程,每个月都会有变动。
|
||
|
||
标准委员会最终决定,标准在每年的6月份正式发布一次,作为当年的正式版本。接下来的时间,就在这个版本的基础上做改动,直到下一年的6月份,草案就自然变成了新一年的版本。这样一来,就不需要以前的版本号了,只要用年份标记就可以了。
|
||
|
||
ES6 的第一个版本,就这样在2015年6月发布了,正式名称就是《ECMAScript 2015标准》(简称 ES2015)。2016年6月,小幅修订的《ECMAScript 2016标准》(简称 ES2016)如期发布,这个版本可以看作是 ES6.1 版,因为两者的差异非常小(只新增了数组实例的`includes`方法和指数运算符),基本上是同一个标准。根据计划,2017年6月发布 ES2017 标准。
|
||
|
||
因此,ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015、ES2016、ES2017等等,而ES2015 则是正式名称,特指该年发布的正式版本的语言标准。本书中提到 ES6 的地方,一般是指 ES2015 标准,但有时也是泛指“下一代 JavaScript 语言”。
|
||
|
||
## 语法提案的批准流程
|
||
|
||
任何人都可以向标准委员会(又称 TC39 委员会)提案,要求修改语言标准。
|
||
|
||
一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。
|
||
|
||
- Stage 0 - Strawman(展示阶段)
|
||
- Stage 1 - Proposal(征求意见阶段)
|
||
- Stage 2 - Draft(草案阶段)
|
||
- Stage 3 - Candidate(候选人阶段)
|
||
- Stage 4 - Finished(定案阶段)
|
||
|
||
一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站[Github.com/tc39/ecma262](https://github.com/tc39/ecma262)查看。
|
||
|
||
本书的写作目标之一,是跟踪 ECMAScript 语言的最新进展,介绍5.1版本以后所有的新语法。对于那些明确或很有希望,将要列入标准的新语法,都将予以介绍。
|
||
|
||
## ECMAScript 的历史
|
||
|
||
ES6 从开始制定到最后发布,整整用了15年。
|
||
|
||
前面提到,ECMAScript 1.0 是1997年发布的,接下来的两年,连续发布了 ECMAScript 2.0(1998年6月)和 ECMAScript 3.0(1999年12月)。3.0版是一个巨大的成功,在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法,以后的版本完全继承。直到今天,初学者一开始学习 JavaScript,其实就是在学3.0版的语法。
|
||
|
||
2000年,ECMAScript 4.0 开始酝酿。这个版本最后没有通过,但是它的大部分内容被 ES6 继承了。因此,ES6 制定的起点其实是2000年。
|
||
|
||
为什么 ES4 没有通过呢?因为这个版本太激进了,对 ES3 做了彻底升级,导致标准委员会的一些成员不愿意接受。ECMA 的第39号技术专家委员会(Technical Committee 39,简称TC39)负责制订 ECMAScript 标准,成员包括 Microsoft、Mozilla、Google 等大公司。
|
||
|
||
2007年10月,ECMAScript 4.0 版草案发布,本来预计次年8月发布正式版本。但是,各方对于是否通过这个标准,发生了严重分歧。以 Yahoo、Microsoft、Google 为首的大公司,反对 JavaScript 的大幅升级,主张小幅改动;以 JavaScript 创造者Brendan Eich为首的Mozilla公司,则坚持当前的草案。
|
||
|
||
2008年7月,由于对于下一个版本应该包括哪些功能,各方分歧太大,争论过于激烈,ECMA 开会决定,中止 ECMAScript 4.0 的开发,将其中涉及现有功能改善的一小部分,发布为 ECMAScript 3.1,而将其他激进的设想扩大范围,放入以后的版本,由于会议的气氛,该版本的项目代号起名为 Harmony(和谐)。会后不久,ECMAScript 3.1 就改名为 ECMAScript 5。
|
||
|
||
2009年12月,ECMAScript 5.0 版正式发布。Harmony 项目则一分为二,一些较为可行的设想定名为 JavaScript.next 继续开发,后来演变成 ECMAScript 6;一些不是很成熟的设想,则被视为 JavaScript.next.next,在更远的将来再考虑推出。TC39 委员会的总体考虑是,ES5 与 ES3 基本保持兼容,较大的语法修正和新功能加入,将由 JavaScript.next 完成。当时,JavaScript.next 指的是ES6,第六版发布以后,就指 ES7。TC39 的判断是,ES5 会在2013年的年中成为 JavaScript 开发的主流标准,并在此后五年中一直保持这个位置。
|
||
|
||
2011年6月,ECMAscript 5.1 版发布,并且成为 ISO 国际标准(ISO/IEC 16262:2011)。
|
||
|
||
2013年3月,ECMAScript 6 草案冻结,不再添加新功能。新的功能设想将被放到 ECMAScript 7。
|
||
|
||
2013年12月,ECMAScript 6 草案发布。然后是12个月的讨论期,听取各方反馈。
|
||
|
||
2015年6月,ECMAScript 6 正式通过,成为国际标准。从2000年算起,这时已经过去了15年。
|
||
|
||
## 部署进度
|
||
|
||
各大浏览器的最新版本,对 ES6 的支持可以查看[kangax.github.io/es5-compat-table/es6/](http://kangax.github.io/es5-compat-table/es6/)。随着时间的推移,支持度已经越来越高了,超过90%的 ES6 语法特性都实现了。
|
||
|
||
Node 是 JavaScript 的服务器运行环境(runtime)。它对 ES6 的支持度更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node 已经实现的 ES6 特性。
|
||
|
||
```bash
|
||
$ node --v8-options | grep harmony
|
||
```
|
||
|
||
上面命令的输出结果,会因为版本的不同而有所不同。
|
||
|
||
我写了一个工具 [ES-Checker](https://github.com/ruanyf/es-checker),用来检查各种运行环境对 ES6 的支持情况。访问[ruanyf.github.io/es-checker](http://ruanyf.github.io/es-checker),可以看到您的浏览器支持 ES6 的程度。运行下面的命令,可以查看你正在使用的 Node 环境对 ES6 的支持程度。
|
||
|
||
```bash
|
||
$ npm install -g es-checker
|
||
$ es-checker
|
||
|
||
=========================================
|
||
Passes 24 feature Dectations
|
||
Your runtime supports 57% of ECMAScript 6
|
||
=========================================
|
||
```
|
||
|
||
## Babel 转码器
|
||
|
||
[Babel](https://babeljs.io/) 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。下面是一个例子。
|
||
|
||
```javascript
|
||
// 转码前
|
||
input.map(item => item + 1);
|
||
|
||
// 转码后
|
||
input.map(function (item) {
|
||
return item + 1;
|
||
});
|
||
```
|
||
|
||
上面的原始代码用了箭头函数,Babel 将其转为普通函数,就能在不支持箭头函数的 JavaScript 环境执行了。
|
||
|
||
### 配置文件`.babelrc`
|
||
|
||
Babel 的配置文件是`.babelrc`,存放在项目的根目录下。使用 Babel 的第一步,就是配置这个文件。
|
||
|
||
该文件用来设置转码规则和插件,基本格式如下。
|
||
|
||
```javascript
|
||
{
|
||
"presets": [],
|
||
"plugins": []
|
||
}
|
||
```
|
||
|
||
`presets`字段设定转码规则,官方提供以下的规则集,你可以根据需要安装。
|
||
|
||
```bash
|
||
# 最新转码规则
|
||
$ 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`。
|
||
|
||
```javascript
|
||
{
|
||
"presets": [
|
||
"latest",
|
||
"react",
|
||
"stage-2"
|
||
],
|
||
"plugins": []
|
||
}
|
||
```
|
||
|
||
注意,以下所有 Babe l工具和模块的使用,都必须先写好`.babelrc`。
|
||
|
||
### 命令行转码`babel-cli`
|
||
|
||
Babel提供`babel-cli`工具,用于命令行转码。
|
||
|
||
它的安装命令如下。
|
||
|
||
```bash
|
||
$ npm install --global babel-cli
|
||
```
|
||
|
||
基本用法如下。
|
||
|
||
```bash
|
||
# 转码结果输出到标准输出
|
||
$ babel example.js
|
||
|
||
# 转码结果写入一个文件
|
||
# --out-file 或 -o 参数指定输出文件
|
||
$ babel example.js --out-file compiled.js
|
||
# 或者
|
||
$ babel example.js -o compiled.js
|
||
|
||
# 整个目录转码
|
||
# --out-dir 或 -d 参数指定输出目录
|
||
$ babel src --out-dir lib
|
||
# 或者
|
||
$ babel src -d lib
|
||
|
||
# -s 参数生成source map文件
|
||
$ babel src -d lib -s
|
||
```
|
||
|
||
上面代码是在全局环境下,进行 Babel 转码。这意味着,如果项目要运行,全局环境必须有 Babel,也就是说项目产生了对环境的依赖。另一方面,这样做也无法支持不同项目使用不同版本的 Babel。
|
||
|
||
一个解决办法是将`babel-cli`安装在项目之中。
|
||
|
||
```bash
|
||
# 安装
|
||
$ npm install --save-dev babel-cli
|
||
```
|
||
|
||
然后,改写`package.json`。
|
||
|
||
```javascript
|
||
{
|
||
// ...
|
||
"devDependencies": {
|
||
"babel-cli": "^6.0.0"
|
||
},
|
||
"scripts": {
|
||
"build": "babel src -d lib"
|
||
},
|
||
}
|
||
```
|
||
|
||
转码的时候,就执行下面的命令。
|
||
|
||
```javascript
|
||
$ npm run build
|
||
```
|
||
|
||
### babel-node
|
||
|
||
`babel-cli`工具自带一个`babel-node`命令,提供一个支持ES6的REPL环境。它支持Node的REPL环境的所有功能,而且可以直接运行ES6代码。
|
||
|
||
它不用单独安装,而是随`babel-cli`一起安装。然后,执行`babel-node`就进入REPL环境。
|
||
|
||
```bash
|
||
$ babel-node
|
||
> (x => x * 2)(1)
|
||
2
|
||
```
|
||
|
||
`babel-node`命令可以直接运行ES6脚本。将上面的代码放入脚本文件`es6.js`,然后直接运行。
|
||
|
||
```bash
|
||
$ babel-node es6.js
|
||
2
|
||
```
|
||
|
||
`babel-node`也可以安装在项目中。
|
||
|
||
```bash
|
||
$ npm install --save-dev babel-cli
|
||
```
|
||
|
||
然后,改写`package.json`。
|
||
|
||
```javascript
|
||
{
|
||
"scripts": {
|
||
"script-name": "babel-node script.js"
|
||
}
|
||
}
|
||
```
|
||
|
||
上面代码中,使用`babel-node`替代`node`,这样`script.js`本身就不用做任何转码处理。
|
||
|
||
### babel-register
|
||
|
||
`babel-register`模块改写`require`命令,为它加上一个钩子。此后,每当使用`require`加载`.js`、`.jsx`、`.es`和`.es6`后缀名的文件,就会先用Babel进行转码。
|
||
|
||
```bash
|
||
$ npm install --save-dev babel-register
|
||
```
|
||
|
||
使用时,必须首先加载`babel-register`。
|
||
|
||
```bash
|
||
require("babel-register");
|
||
require("./index.js");
|
||
```
|
||
|
||
然后,就不需要手动对`index.js`转码了。
|
||
|
||
需要注意的是,`babel-register`只会对`require`命令加载的文件转码,而不会对当前文件转码。另外,由于它是实时转码,所以只适合在开发环境使用。
|
||
|
||
### babel-core
|
||
|
||
如果某些代码需要调用 Babel 的 API 进行转码,就要使用`babel-core`模块。
|
||
|
||
安装命令如下。
|
||
|
||
```bash
|
||
$ npm install babel-core --save
|
||
```
|
||
|
||
然后,在项目中就可以调用`babel-core`。
|
||
|
||
```javascript
|
||
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`,可以参看官方文档[http://babeljs.io/docs/usage/options/](http://babeljs.io/docs/usage/options/)。
|
||
|
||
下面是一个例子。
|
||
|
||
```javascript
|
||
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};'
|
||
```
|
||
|
||
上面代码中,`transform`方法的第一个参数是一个字符串,表示需要被转换的ES6代码,第二个参数是转换的配置对象。
|
||
|
||
### babel-polyfill
|
||
|
||
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如`Iterator`、`Generator`、`Set`、`Maps`、`Proxy`、`Reflect`、`Symbol`、`Promise`等全局对象,以及一些定义在全局对象上的方法(比如`Object.assign`)都不会转码。
|
||
|
||
举例来说,ES6在`Array`对象上新增了`Array.from`方法。Babel 就不会转码这个方法。如果想让这个方法运行,必须使用`babel-polyfill`,为当前环境提供一个垫片。
|
||
|
||
安装命令如下。
|
||
|
||
```bash
|
||
$ npm install --save babel-polyfill
|
||
```
|
||
|
||
然后,在脚本头部,加入如下一行代码。
|
||
|
||
```javascript
|
||
import 'babel-polyfill';
|
||
// 或者
|
||
require('babel-polyfill');
|
||
```
|
||
|
||
Babel 默认不转码的 API 非常多,详细清单可以查看`babel-plugin-transform-runtime`模块的[definitions.js](https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-runtime/src/definitions.js)文件。
|
||
|
||
### 浏览器环境
|
||
|
||
Babel 也可以用于浏览器环境。但是,从 Babel 6.0 开始,不再直接提供浏览器版本,而是要用构建工具构建出来。如果你没有或不想使用构建工具,可以使用[babel-standalone](https://github.com/Daniel15/babel-standalone)模块提供的浏览器版本,将其插入网页。
|
||
|
||
```html
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script>
|
||
<script type="text/babel">
|
||
// Your ES6 code
|
||
</script>
|
||
```
|
||
|
||
注意,网页实时将 ES6 代码转为 ES5,对性能会有影响。生产环境需要加载已经转码完成的脚本。
|
||
|
||
下面是如何将代码打包成浏览器可以使用的脚本,以`Babel`配合`Browserify`为例。首先,安装`babelify`模块。
|
||
|
||
```bash
|
||
$ npm install --save-dev babelify babel-preset-latest
|
||
```
|
||
|
||
然后,再用命令行转换 ES6 脚本。
|
||
|
||
```bash
|
||
$ browserify script.js -o bundle.js \
|
||
-t [ babelify --presets [ latest ] ]
|
||
```
|
||
|
||
上面代码将ES6脚本`script.js`,转为`bundle.js`,浏览器直接加载后者就可以了。
|
||
|
||
在`package.json`设置下面的代码,就不用每次命令行都输入参数了。
|
||
|
||
```javascript
|
||
{
|
||
"browserify": {
|
||
"transform": [["babelify", { "presets": ["latest"] }]]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 在线转换
|
||
|
||
Babel 提供一个[REPL在线编译器](https://babeljs.io/repl/),可以在线将 ES6 代码转为 ES5 代码。转换后的代码,可以直接作为 ES5 代码插入网页运行。
|
||
|
||
### 与其他工具的配合
|
||
|
||
许多工具需要 Babel 进行前置转码,这里举两个例子:ESLint 和 Mocha。
|
||
|
||
ESLint 用于静态检查代码的语法和风格,安装命令如下。
|
||
|
||
```bash
|
||
$ npm install --save-dev eslint babel-eslint
|
||
```
|
||
|
||
然后,在项目根目录下,新建一个配置文件`.eslintrc`,在其中加入`parser`字段。
|
||
|
||
```javascript
|
||
{
|
||
"parser": "babel-eslint",
|
||
"rules": {
|
||
...
|
||
}
|
||
}
|
||
```
|
||
|
||
再在`package.json`之中,加入相应的`scripts`脚本。
|
||
|
||
```javascript
|
||
{
|
||
"name": "my-module",
|
||
"scripts": {
|
||
"lint": "eslint my-files.js"
|
||
},
|
||
"devDependencies": {
|
||
"babel-eslint": "...",
|
||
"eslint": "..."
|
||
}
|
||
}
|
||
```
|
||
|
||
Mocha 则是一个测试框架,如果需要执行使用 ES6 语法的测试脚本,可以修改`package.json`的`scripts.test`。
|
||
|
||
```javascript
|
||
"scripts": {
|
||
"test": "mocha --ui qunit --compilers js:babel-core/register"
|
||
}
|
||
```
|
||
|
||
上面命令中,`--compilers`参数指定脚本的转码器,规定后缀名为`js`的文件,都需要使用`babel-core/register`先转码。
|
||
|
||
## Traceur 转码器
|
||
|
||
Google公司的[Traceur](https://github.com/google/traceur-compiler)转码器,也可以将 ES6 代码转为 ES5 代码。
|
||
|
||
### 直接插入网页
|
||
|
||
Traceur 允许将 ES6 代码直接插入网页。首先,必须在网页头部加载 Traceur 库文件。
|
||
|
||
```html
|
||
<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
|
||
<script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
|
||
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
|
||
<script type="module">
|
||
import './Greeter.js';
|
||
</script>
|
||
```
|
||
|
||
上面代码中,一共有4个`script`标签。第一个是加载 Traceur 的库文件,第二个和第三个是将这个库文件用于浏览器环境,第四个则是加载用户脚本,这个脚本里面可以使用ES6代码。
|
||
|
||
注意,第四个`script`标签的`type`属性的值是`module`,而不是`text/javascript`。这是 Traceur 编译器识别 ES6 代码的标志,编译器会自动将所有`type=module`的代码编译为 ES5,然后再交给浏览器执行。
|
||
|
||
除了引用外部 ES6 脚本,也可以直接在网页中放置 ES6 代码。
|
||
|
||
```javascript
|
||
<script type="module">
|
||
class Calc {
|
||
constructor() {
|
||
console.log('Calc constructor');
|
||
}
|
||
add(a, b) {
|
||
return a + b;
|
||
}
|
||
}
|
||
|
||
var c = new Calc();
|
||
console.log(c.add(4,5));
|
||
</script>
|
||
```
|
||
|
||
正常情况下,上面代码会在控制台打印出`9`。
|
||
|
||
如果想对 Traceur 的行为有精确控制,可以采用下面参数配置的写法。
|
||
|
||
```javascript
|
||
<script>
|
||
// Create the System object
|
||
window.System = new traceur.runtime.BrowserTraceurLoader();
|
||
// Set some experimental options
|
||
var metadata = {
|
||
traceurOptions: {
|
||
experimental: true,
|
||
properTailCalls: true,
|
||
symbols: true,
|
||
arrayComprehension: true,
|
||
asyncFunctions: true,
|
||
asyncGenerators: exponentiation,
|
||
forOn: true,
|
||
generatorComprehension: true
|
||
}
|
||
};
|
||
// Load your module
|
||
System.import('./myModule.js', {metadata: metadata}).catch(function(ex) {
|
||
console.error('Import failed', ex.stack || ex);
|
||
});
|
||
</script>
|
||
```
|
||
|
||
上面代码中,首先生成Traceur的全局对象`window.System`,然后`System.import`方法可以用来加载 ES6。加载的时候,需要传入一个配置对象`metadata`,该对象的`traceurOptions`属性可以配置支持 ES6 功能。如果设为`experimental: true`,就表示除了 ES6 以外,还支持一些实验性的新功能。
|
||
|
||
### 在线转换
|
||
|
||
Traceur也提供一个[在线编译器](http://google.github.io/traceur-compiler/demo/repl.html),可以在线将 ES6 代码转为 ES5 代码。转换后的代码,可以直接作为 ES5 代码插入网页运行。
|
||
|
||
上面的例子转为 ES5 代码运行,就是下面这个样子。
|
||
|
||
```javascript
|
||
<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
|
||
<script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
|
||
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
|
||
<script>
|
||
$traceurRuntime.ModuleStore.getAnonymousModule(function() {
|
||
"use strict";
|
||
|
||
var Calc = function Calc() {
|
||
console.log('Calc constructor');
|
||
};
|
||
|
||
($traceurRuntime.createClass)(Calc, {add: function(a, b) {
|
||
return a + b;
|
||
}}, {});
|
||
|
||
var c = new Calc();
|
||
console.log(c.add(4, 5));
|
||
return {};
|
||
});
|
||
</script>
|
||
```
|
||
|
||
### 命令行转换
|
||
|
||
作为命令行工具使用时,Traceur 是一个 Node 的模块,首先需要用 Npm 安装。
|
||
|
||
```bash
|
||
$ npm install -g traceur
|
||
```
|
||
|
||
安装成功后,就可以在命令行下使用 Traceur 了。
|
||
|
||
Traceur 直接运行 ES6 脚本文件,会在标准输出显示运行结果,以前面的`calc.js`为例。
|
||
|
||
```bash
|
||
$ traceur calc.js
|
||
Calc constructor
|
||
9
|
||
```
|
||
|
||
如果要将 ES6 脚本转为 ES5 保存,要采用下面的写法。
|
||
|
||
```bash
|
||
$ traceur --script calc.es6.js --out calc.es5.js
|
||
```
|
||
|
||
上面代码的`--script`选项表示指定输入文件,`--out`选项表示指定输出文件。
|
||
|
||
为了防止有些特性编译不成功,最好加上`--experimental`选项。
|
||
|
||
```bash
|
||
$ traceur --script calc.es6.js --out calc.es5.js --experimental
|
||
```
|
||
|
||
命令行下转换生成的文件,就可以直接放到浏览器中运行。
|
||
|
||
### Node 环境的用法
|
||
|
||
Traceur 的 Node用法如下(假定已安装`traceur`模块)。
|
||
|
||
```javascript
|
||
var traceur = require('traceur');
|
||
var fs = require('fs');
|
||
|
||
// 将ES6脚本转为字符串
|
||
var contents = fs.readFileSync('es6-file.js').toString();
|
||
|
||
var result = traceur.compile(contents, {
|
||
filename: 'es6-file.js',
|
||
sourceMap: true,
|
||
// 其他设置
|
||
modules: 'commonjs'
|
||
});
|
||
|
||
if (result.error)
|
||
throw result.error;
|
||
|
||
// result对象的js属性就是转换后的ES5代码
|
||
fs.writeFileSync('out.js', result.js);
|
||
// sourceMap属性对应map文件
|
||
fs.writeFileSync('out.js.map', result.sourceMap);
|
||
```
|
||
|