你們知道,將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便可