你们知道,将ES6代码编译为ES5时,咱们经常使用到Babel这个编译工具。你们参考一些网上的文章或者官方文档,里面常会建议你们在.babelrc中输入以下代码:react
{ "presets": [ "es2015", "react", "stage-0" ], "plugins": [] }
babel 总共分为三个阶段:解析,转换,生成。
咱们须要知道如今 babel 自己是不具有这种转化功能,提供这些转化功能的是一个个 plugin。因此咱们没有配置任何 plugin 的时候,通过 Babel 输出的代码是没有改变的
下面咱们来了解一下Babel中的stage-0、stage-一、stage-二、stage-3ji及它们支持的一些插件webpack
为何说“stage-0” 法力无边呢,由于它包含stage-1, stage-2以及stage-3的全部功能,同时还另外支持以下两个功能插件:web
transform-do-expressions transform-function-bind
用过React的同窗可能知道,jsx对条件表达式支持的不是太好,你不能很方便的使用if/else表达式,要么你使用三元表达,要么用函数。例如你不能写以下的代码:express
var App = React.createClass({ render(){ let { color } = this.props; return ( <div className="parents"> { if(color == 'blue') { <BlueComponent/>; }else if(color == 'red') { <RedComponent/>; }else { <GreenComponent/>; } } } </div> ) } })
在React中你只能写成这样:数组
var App = React.createClass({ render(){ let { color } = this.props; const getColoredComponent = color => { if(color === 'blue') { return <BlueComponent/>; } if(color === 'red') { return <RedComponent/>; } if(color === 'green') { return <GreenComponent/>; } } return ( <div className="parents"> { getColoredComponent(color) } </div> ) } })
transform-do-expressions 这个插件就是为了方便在 jsx写if/else表达式而提出的,咱们能够重写下代码。babel
var App = React.createClass({ render(){ let { color } = this.props; return ( <div className="parents"> {do { if(color == 'blue') { <BlueComponent/>; }else if(color == 'red') { <RedComponent/>; }else { <GreenComponent/>; } } }} </div> ) } })
再说说 transform-function-bind, 这个插件其实就是提供过 :: 这个操做符来方便快速切换上下文, 以下面的代码:异步
obj::func // is equivalent to: func.bind(obj) obj::func(val) // is equivalent to: func.call(obj, val) ::obj.func(val) // is equivalent to: func.call(obj, val) // 再来一个复杂点的样例 const box = { weight: 2, getWeight() { return this.weight; }, }; const { getWeight } = box; console.log(box.getWeight()); // prints '2' const bigBox = { weight: 10 }; console.log(bigBox::getWeight()); // prints '10' // Can be chained: function add(val) { return this + val; } console.log(bigBox::getWeight()::add(5)); // prints '15'
stage-1除了包含stage-2和stage-3,还包含了下面4个插件:async
transform-class-constructor-call (Deprecated) transform-class-properties transform-decorators – disabled pending proposal update transform-export-extensions
为何说 stage-2深藏不露呢,由于它很低调,低调到你能够忽略它,但事实上,它颇有内涵的。它除了覆盖stage-3的全部功能,还支持以下两个插件:函数
syntax-trailing-function-commas transform-object-reset-spread
syntax-trailing-function-commas这个插件它不是对ES6功能的增长,而是为了加强代码的可读性和可修改性而提出的工具
// 假设有以下的一个函数,它有两个参数 function clownPuppiesEverywhere( param1, param2 ) { /* ... */ } clownPuppiesEverywhere( 'foo', 'bar' ); // 有一天,它须要变成3个参数,你须要这样修改 function clownPuppiesEverywhere( param1, - param2 + param2, // 这一行得加一个逗号 + param3 // 增长参数param3 ) { /* ... */ } clownPuppiesEverywhere( 'foo', - 'bar' + 'bar', // 这里的修改成逗号 + 'baz' // 增长新的参数 );
// 咱们来从新定义一下函数
function clownPuppiesEverywhere( param1, param2, // 注意这里,咱们加了一个逗号哟 ) { /* ... */ } clownPuppiesEverywhere( 'foo', 'bar', // 这里咱们也加了一个逗号 ); // 如今函数须要三个参数,咱们来修改下 function clownPuppiesEverywhere( param1, param2, + param3, // 增长params3参数 ) { /* ... */ }
stage-2中的syntax-trailing-function-commas就是有"尾逗号函数”功能
transform-object-rest-spread
再来讲transform-object-rest-spread, 其实它是对 ES6中解构赋值的一个扩展,由于ES6只支持对数组的解构赋值,对对象是不支持的。以下面的代码所示:
// 获取剩下的属性
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } // 属性展开 let n = { x, y, ...z }; console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
为啥说stage3大放异彩呢?由于它支持大名鼎鼎的async和await, 这两个哥们但是解决(Ajax)回调函数的终极解决方法呀!管你什么异步,我均可以用同步的思惟来写,ES7里面很是强悍的存在。总的来讲,它包含以下两个插件:
transform-async-to-generator transform-exponentiation-operator
transform-async-to-generator主要用来支持ES7中的async和await
提示: 因为asycn和await是ES7里面的内容,现阶段不建议使用。为了顺利运行上面的代码,建议用webpack进行编译。
transform-exponentiation-operator
transform-exponentiation-operator这个插件算是一个语法糖,能够经过**这个符号来进行幂操做,想当于Math.pow(a,b)。以下面的样例
// x ** y let squared = 2 ** 2; // 至关于: 2 * 2 let cubed = 2 ** 3; // 至关于: 2 * 2 * 2 // x **= y let a = 2; a **= 2; // 至关于: a = a * a; let b = 3; b **= 3; // 至关于: b = b * b * b;
结语:在进行实际开发时,能够更具须要来设置对应的stage。若是省事懒得折腾,通常设置为stage-0便可。若是为了防止开发人员使用某些太新的功能,咱们能够限制到某个特定的stage便可