ES6是什么?
實際上, 它是一種新的javascript規范。
下面就是一個簡單的JavaScript發展時間軸:
1、1995:JavaScript誕生,它的初始名叫LiveScript。
2、1997:ECMAScript標准確立。
3、1999:ES3出現,與此同時IE5風靡一時。
4、2000–2005: XMLHttpRequest又名AJAX, 在Outlook Web Access (2000)、Oddpost (2002),Gmail (2004)和Google Maps (2005)大受重用。
5、2009: ES5出現,(就是我們大多數人現在使用的)例如foreach,Object.keys,Object.create和JSON標准。
6、2015:ES6/ECMAScript2015出現。
1.Default Parameters(默認參數) in ES6
還記得我們以前(ES5)不得不通過下面方式來定義默認參數:
var link = function (height, color, url) { var height = height || 50; var color = color || 'red'; }
但在ES6,我們可以直接把默認值放在函數申明里:
var link = function(height = 50, color = 'red', url = 'http://azat.co') { ... }
2.Template Literals(模板對象) in ES6
在其它語言中,使用模板和插入值是在字符串里面輸出變量的一種方式。
因此,在ES5,我們可以這樣組合一個字符串:
var name = 'Your name is ' + first + ' ' + last + '.'; var url = 'http://localhost:3000/api/messages/' + id;
幸運的是,在ES6中,我們可以使用新的語法$ {NAME},並把它放在反引號里:
var name = `Your name is ${first} ${last}. `; var url = `http://localhost:3000/api/messages/${id}`;
3.Multi-line Strings (多行字符串)in ES6
ES6的多行字符串是一個非常實用的功能。
在ES5中,我們不得不使用以下方法來表示多行字符串:
var roadPoem = 'Then took the other, as just as fair,nt' + 'And having perhaps the better claimnt' + 'Because it was grassy and wanted wear,nt' + 'Though as for that the passing therent' + 'Had worn them really about the same,nt'; var fourAgreements = 'You have the right to be you.n You can only be you when you do your best.';
然而在ES6中,僅僅用反引號就可以解決了:
var roadPoem = `Then took the other, as just as fair, And having perhaps the better claim Because it was grassy and wanted wear, Though as for that the passing there Had worn them really about the same,`; var fourAgreements = `You have the right to be you. You can only be you when you do your best.`;
4.Destructuring Assignment (解構賦值)in ES6
解構可能是一個比較難以掌握的概念。先從一個簡單的賦值講起,其中house 和 mouse是key,同時house 和mouse也是一個變量,
在ES5中是這樣:
// data has properties house and mouse var data = $('body').data(); var house = data.house, var mouse = data.mouse;
以及在node.js中用ES5是這樣:
var jsonMiddleware = require('body-parser').jsonMiddleware ; // body has username and password var body = req.body; var username = body.username, var password = body.password;
在ES6,我們可以使用這些語句代替上面的ES5代碼:
// we'll get house and mouse variables var { house, mouse } = $('body').data(); var { jsonMiddleware } = require('body-parser'); var { username, password } = req.body;
這個同樣也適用於數組,非常贊的用法:
var [col1, col2] = $('.column'); var [line1, line2, line3, , line5] = file.split('n');
我們可能需要一些時間來習慣解構賦值語法的使用,但是它確實能給我們帶來許多意外的收獲。
5.Enhanced Object Literals (增強的對象字面量)in ES6
使用對象文本可以做許多讓人意想不到的事情!通過ES6,我們可以把ES5中的JSON變得更加接近於一個類。
下面是一個典型ES5對象文本,里面有一些方法和屬性:
var serviceBase = { port: 3000, url: 'azat.co', }; var getAccounts = function() { return [1,2,3]; }; var accountServiceES5 = { port: serviceBase.port, url: serviceBase.url, getAccounts: getAccounts, toString: function() { return JSON.stringify(this.valueOf()); }, getUrl: function() { return "http://" + this.url + ':' + this.port; }, valueOf_1_2_3: getAccounts(), }
如果我們想讓它更有意思,我們可以用Object.create從serviceBase繼承原型的方法:
var accountServiceES5ObjectCreate = Object.create(serviceBase); var accountServiceES5ObjectCreate = { getAccounts: getAccounts, toString: function() { return JSON.stringify(this.valueOf()); }, getUrl: function() { return 'http://' + this.url + ':' + this.port; }, valueOf_1_2_3: getAccounts(), }
6.Arrow Functions in(箭頭函數) ES6
這是我迫不及待想講的一個特征,CoffeeScript 就是因為它豐富的箭頭函數讓很多開發者喜愛。在ES6中,也有了豐富的箭頭函數。
這些豐富的箭頭是令人驚訝的因為它們將使許多操作變成現實,比如:
以前我們使用閉包,this總是預期之外地產生改變,而箭頭函數的迷人之處在於,現在你的this可以按照你的預期使用了,身處箭頭函數里面,this還是原來的this。
有了箭頭函數在ES6中, 我們就不必用that = this或 self = this 或 _this = this 或.bind(this)。
例如,下面的代碼用ES5就不是很優雅:
var _this = this; $('.btn').click(function(event) { _this.sendData(); });
在ES6中就不需要用 _this = this:
$('.btn').click((event) => {
this.sendData();
});
不幸的是,ES6委員會決定,以前的function的傳遞方式也是一個很好的方案,所以它們仍然保留了以前的功能。
下面這是一個另外的例子,我們通過call傳遞文本給logUpperCase() 函數在ES5中:
var logUpperCase = function() { var _this = this; this.string = this.string.toUpperCase(); return function () { return console.log(_this.string); } }; logUpperCase.call({ string: 'ES6 rocks' })();
而在ES6,我們並不需要用_this浪費時間:
var logUpperCase = function() { this.string = this.string.toUpperCase(); return () => console.log(this.string); }; logUpperCase.call({ string: 'ES6 rocks' })();
7. Promises in ES6
Promises 是一個有爭議的話題。因此有許多略微不同的promise 實現語法。Q,bluebird,deferred.js,vow, avow, jquery 一些可以列出名字的。
也有人說我們不需要promises,僅僅使用異步,生成器,回調等就夠了。但令人高興的是,在ES6中有標准的Promise實現。
下面是一個簡單的用setTimeout()實現的異步延遲加載函數:
setTimeout(function() { console.log('Yay!'); }, 1000);
在ES6中,我們可以用promise重寫:
var wait1000 = new Promise(function(resolve, reject) { setTimeout(resolve, 1000); }).then(function() { console.log('Yay!'); });
或者用ES6的箭頭函數:
var wait1000 = new Promise((resolve, reject)=> { setTimeout(resolve, 1000); }).then(()=> { console.log('Yay!'); });
8.Block-Scoped Constructs Let and Const(塊作用域和構造let和const)
在ES6代碼中,你可能已經看到那熟悉的身影let。在ES6里let並不是一個花俏的特性,它是更復雜的。
Let是一種新的變量申明方式,它允許你把變量作用域控制在塊級里面。我們用大括號定義代碼塊,在ES5中,塊級作用域起不了任何作用:
function calculateTotalAmount (vip) { var amount = 0; if (vip) { var amount = 1; } // more crazy blocks! { var amount = 100; { var amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));
結果將返回1000,這真是一個bug。
在ES6中,我們用let限制塊級作用域。而var是限制函數作用域。
function calculateTotalAmount (vip) { // probably should also be let, but you can mix var and let var amount = 0; if (vip) { // first amount is still 0 let amount = 1; } // more crazy blocks! { // first amount is still 0 let amount = 100; { // first amount is still 0 let amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));
這個結果將會是0,因為塊作用域中有了let。如果(amount=1).那么這個表達式將返回1。談到const,就更加容易了;
它就是一個不變量,也是塊級作用域就像let一樣。
下面是一個演示,這里有一堆常量,它們互不影響,因為它們屬於不同的塊級作用域:
function calculateTotalAmount (vip) { const amount = 0; if (vip) { const amount = 1; } // more crazy blocks! { const amount = 100 ; { const amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));
從我個人看來,let 和const使這個語言變復雜了。沒有它們的話,我們只需考慮一種方式,現在有許多種場景需要考慮。
