ECMAScript 6(如下簡稱ES6)是JavaScript語言的下一代標準,已經在2015年6月正式發佈了。它的目標,是使得JavaScript語言能夠用來編寫複雜的大型應用程序,成爲企業級開發語言。javascript
標準的制定者有計劃,之後每一年發佈一次標準,使用年份做爲標準的版本。由於當前版本的ES6是在2015年發佈的,因此又稱ECMAScript 2015。也就是說,ES6就是ES2015,下一年應該會發布小幅修訂的ES2016。html
一個常見的問題是,ECMAScript和JavaScript究竟是什麼關係?java
要講清楚這個問題,須要回顧歷史。1996年11月,JavaScript的創造者Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,但願這種語言可以成爲國際標準。次年,ECMA發佈262號標準文件(ECMA-262)的初版,規定了瀏覽器腳本語言的標準,並將這種語言稱爲ECMAScript,這個版本就是1.0版。node
該標準從一開始就是針對JavaScript語言制定的,可是之因此不叫JavaScript,有兩個緣由。一是商標,Java是Sun公司的商標,根據受權協議,只有Netscape公司能夠合法地使用JavaScript這個名字,且JavaScript自己也已經被Netscape公司註冊爲商標。二是想體現這門語言的制定者是ECMA,不是Netscape,這樣有利於保證這門語言的開放性和中立性。git
所以,ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。在平常場合,這兩個詞是能夠互換的。es6
ES6從開始制定到最後發佈,整整用了15年。github
前面提到,ECMAScript 1.0是1997年發佈的,接下來的兩年,連續發佈了ECMAScript 2.0(1998年6月)和ECMAScript 3.0(1999年12月)。3.0版是一個巨大的成功,在業界獲得普遍支持,成爲通行標準,奠基了JavaScript語言的基本語法,之後的版本徹底繼承。直到今天,初學者一開始學習JavaScript,其實就是在學3.0版的語法。npm
2000年,ECMAScript 4.0開始醞釀。這個版本最後沒有經過,可是它的大部份內容被ES6繼承了。所以,ES6制定的起點實際上是2000年。json
爲何ES4沒有經過呢?由於這個版本太激進了,對ES3作了完全升級,致使標準委員會的一些成員不肯意接受。2007年10月,ECMAScript 4.0版草案發布,原本預計次年8月發佈正式版本。可是,各方對因而否經過這個標準,發生了嚴重分歧。以Yahoo、Microsoft、Google爲首的大公司,反對JavaScript的大幅升級,主張小幅改動;以JavaScript創造者Brendan Eich爲首的Mozilla公司,則堅持當前的草案。bootstrap
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,在更遠的未來再考慮推出。
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年。
ECMA的第39號技術專家委員會(Technical Committee 39,簡稱TC39)負責制訂ECMAScript標準,成員包括Microsoft、Mozilla、Google等大公司。TC39的整體考慮是,ES5與ES3基本保持兼容,較大的語法修正和新功能加入,將由JavaScript.next完成。當時,JavaScript.next指的是ES6,第六版發佈之後,就指ES7。TC39的判斷是,ES5會在2013年的年中成爲JavaScript開發的主流標準,並在此後五年中一直保持這個位置。
各大瀏覽器的最新版本,對ES6的支持能夠查看kangax.github.io/es5-compat-table/es6/。隨着時間的推移,支持度已經愈來愈高了,ES6的大部分特性都實現了。
Node.js是JavaScript語言的服務器運行環境,對ES6的支持度比瀏覽器更高。經過Node,能夠體驗更多ES6的特性。建議使用版本管理工具nvm,來安裝Node,由於能夠自由切換版本。不過,nvm
不支持Windows系統,若是你使用Windows系統,下面的操做能夠改用nvmw或nvm-windows代替。
安裝nvm須要打開命令行窗口,運行下面的命令。
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/<version number>/install.sh | bash
上面命令的version number
處,須要用版本號替換。本節寫做時的版本號是v0.29.0
。該命令運行後,nvm
會默認安裝在用戶主目錄的.nvm
子目錄。
而後,激活nvm
。
$ source ~/.nvm/nvm.sh
激活之後,安裝Node的最新版。
$ nvm install node
安裝完成後,切換到該版本。
$ nvm use node
使用下面的命令,能夠查看Node全部已經實現的ES6特性。
$ node --v8-options | grep harmony --harmony_typeof --harmony_scoping --harmony_modules --harmony_symbols --harmony_proxies --harmony_collections --harmony_observation --harmony_generators --harmony_iteration --harmony_numeric_literals --harmony_strings --harmony_arrays --harmony_maths --harmony
上面命令的輸出結果,會由於版本的不一樣而有所不一樣。
我寫了一個ES-Checker模塊,用來檢查各類運行環境對ES6的支持狀況。訪問ruanyf.github.io/es-checker,能夠看到您的瀏覽器支持ES6的程度。運行下面的命令,能夠查看本機支持ES6的程度。
$ npm install -g es-checker $ es-checker ========================================= Passes 24 feature Dectations Your runtime supports 57% of ECMAScript 6 =========================================
Babel是一個普遍使用的ES6轉碼器,能夠將ES6代碼轉爲ES5代碼,從而在瀏覽器或其餘環境執行。這意味着,你能夠用ES6的方式編寫程序,又不用擔憂現有環境是否支持。下面是一個例子。
// 轉碼前 input.map(item => item + 1); // 轉碼後 input.map(function (item) { return item + 1; });
上面的原始代碼用了箭頭函數,這個特性尚未獲得普遍支持,Babel將其轉爲普通函數,就能在現有的JavaScript環境執行了。
命令行下,Babel的安裝命令以下。
$ npm install --global babel
Babel自帶一個babel-node
命令,提供支持ES6的REPL環境。它支持Node的REPL環境的全部功能,並且能夠直接運行ES6代碼。
$ babel-node > > console.log([1,2,3].map(x => x * x)) [ 1, 4, 9 ] >
babel-node
命令也能夠直接運行ES6腳本。假定將上面的代碼放入腳本文件es6.js
。
$ babel-node es6.js [1, 4, 9]
babel
命令能夠將ES6代碼轉爲ES5代碼。
$ babel es6.js "use strict"; console.log([1, 2, 3].map(function (x) { return x * x; }));
-o
參數將轉換後的代碼,從標準輸出導入文件。
$ babel es6.js -o es5.js # 或者 $ babel es6.js --out-file es5.js
-d
參數用於轉換整個目錄。
$ babel -d build-dir source-dir
注意,-d
參數後面跟的是輸出目錄。
若是但願生成source map文件,則要加上-s
參數。
$ babel -d build-dir source-dir -s
Babel也能夠用於瀏覽器。它的瀏覽器版本,能夠經過安裝babel-core
模塊獲取。
$ npm install babel-core
運行上面的命令之後,就能夠在當前目錄的node_modules/babel-core/
子目錄裏面,找到babel
的瀏覽器版本browser.js
(未精簡)和browser.min.js
(已精簡)。
而後,將下面的代碼插入網頁。
<script src="node_modules/babel-core/browser.js"></script> <script type="text/babel"> // Your ES6 code </script>
上面代碼中,browser.js
是Babel提供的轉換器腳本,能夠在瀏覽器運行。用戶的ES6腳本放在script
標籤之中,可是要註明type="text/babel"
。
這種寫法是實時將ES6代碼轉爲ES5,對網頁性能會有影響。生產環境須要加載已經轉碼完成的腳本。
Babel
配合Browserify
一塊兒使用,能夠生成瀏覽器可以直接加載的腳本。
$ browserify script.js -t babelify --outfile bundle.js
上面代碼將ES6腳本script.js
,轉爲bundle.js
。瀏覽器直接加載後者就能夠了,不用再加載browser.js
。
在package.json
設置下面的代碼,就不用每次命令行都輸入參數了。
{ // ... "browserify": { "transform": [ ["babelify", { "stage": [0] }] ] } }
Node腳本之中,須要轉換ES6腳本,能夠像下面這樣寫。
先安裝babel-core
。
$ npm install --save-dev babel-core
而後在腳本中,調用babel-core
的transform
方法。
require("babel-core").transform("code", options);
上面代碼中,transform
方法的第一個參數是一個字符串,表示ES6代碼。
Node腳本還有一種特殊的babel
用法,即把babel
加載爲require
命令的一個鉤子。先將babel
全局安裝。
$ npm install -g babel
而後,在你的應用的入口腳本(entry script)頭部,加入下面的語句。
require("babel/register");
有了上面這行語句,後面全部經過require
命令加載的後綴名爲.es6
、.es
、.jsx
和.js
的腳本,都會先經過babel
轉碼後再加載。
Google公司的Traceur轉碼器,也能夠將ES6代碼轉爲ES5代碼。
Traceur容許將ES6代碼直接插入網頁。首先,必須在網頁頭部加載Traceur庫文件。
<!-- 加載Traceur編譯器 --> <script src="http://google.github.io/traceur-compiler/bin/traceur.js" type="text/javascript"></script> <!-- 將Traceur編譯器用於網頁 --> <script src="http://google.github.io/traceur-compiler/src/bootstrap.js" type="text/javascript"></script> <!-- 打開實驗選項,不然有些特性可能編譯不成功 --> <script> traceur.options.experimental = true; </script>
接下來,就能夠把ES6代碼放入上面這些代碼的下方。
<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。
注意,script
標籤的type
屬性的值是module
,而不是text/javascript
。這是Traceur編譯器識別ES6代碼的標識,編譯器會自動將全部type=module
的代碼編譯爲ES5,而後再交給瀏覽器執行。
若是ES6代碼是一個外部文件,也能夠用script
標籤插入網頁。
<script type="module" src="calc.js" > </script>
Traceur提供一個在線編譯器,能夠在線將ES6代碼轉爲ES5代碼。轉換後的代碼,能夠直接做爲ES5代碼插入網頁運行。
上面的例子轉爲ES5代碼運行,就是下面這個樣子。
<script src="http://google.github.io/traceur-compiler/bin/traceur.js" type="text/javascript"></script> <script src="http://google.github.io/traceur-compiler/src/bootstrap.js" type="text/javascript"></script> <script> traceur.options.experimental = true; </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.js的模塊,首先須要用npm安裝。
$ npm install -g traceur
安裝成功後,就能夠在命令行下使用traceur了。
traceur直接運行es6腳本文件,會在標準輸出顯示運行結果,之前面的calc.js爲例。
$ traceur calc.js Calc constructor 9
若是要將ES6腳本轉爲ES5保存,要採用下面的寫法
$ traceur --script calc.es6.js --out calc.es5.js
上面代碼的--script
選項表示指定輸入文件,--out
選項表示指定輸出文件。
爲了防止有些特性編譯不成功,最好加上--experimental
選項。
$ traceur --script calc.es6.js --out calc.es5.js --experimental
命令行下轉換的文件,就能夠放到瀏覽器中運行。
Traceur的Node.js用法以下(假定已安裝traceur模塊)。
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);
2013年3月,ES6的草案封閉,再也不接受新功能了。新的功能將被加入ES7。
任何人均可以向TC39提案,從提案到變成正式標準,須要經歷五個階段。每一個階段的變更都須要由TC39委員會批准。
一個提案只要能進入Stage 2,就差很少等於確定會包括在ES7裏面。
本書的寫做目標之一,是跟蹤ECMAScript語言的最新進展。對於那些明確的、或者頗有但願列入ES7的功能,尤爲是那些Babel已經支持的功能,都將予以介紹。
本書介紹的ES7功能清單以下。
Stage 0:
Stage 1:
Stage 2:
ECMAScript當前的全部提案,能夠在TC39的官方網站Github.com/tc39/ecma262查看。
Babel轉碼器對Stage 2及以上階段的功能,是默認支持的。對於那些默認沒有打開的功能,須要手動打開。
$ babel --stage 0 $ babel --optional es7.decorators本文轉載自:http://es6.ruanyifeng.com/#docs/intro