一文看懂ES6十大特性
- Default Parameters(預設引數) in ES6
- Template Literals (模板文字)in ES6
- Multi-line Strings (多行字串)in ES6
- Destructuring Assignment (解構賦值)in ES6
- Enhanced Object Literals (增強的物件文字)in ES6
- Arrow Functions (箭頭函式)in ES6
- Promises in ES6
- Block-Scoped Constructs Let and Const(塊作用域構造Let and Const)
- Classes(類) in ES6
- Modules(模組) in ES6
1.Default Parameters(預設引數)
ES5:
var link = function (height, color, url) { var height = height || 50; var color = color || 'red'; var url = url || 'http://azat.co'; ... }
ES6:直接寫在引數裡
var link = function(height = 50, color = 'red', url = 'http://azat.co') { ... }
好處
節省了程式碼量。
2.Template Literals(模板物件)
在字串裡面輸出變數
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://loalhost:3000/api/messages/${id}';
好處
: 這裡的$ {NAME}直接當做字串用,無需寫加號
3.Multi-line Strings (多行字串)
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 theren Had worn them really about the same,`; var fourAgreements = `You have the right to be you.n You can only be you when you do your best.`;
好處
:直接一個反引號,將所有的字串放進去即可,中介隨意換行,好清爽!
4.Destructuring Assignment (解構賦值)
下邊例子中,house 和 mouse是 key,同時 house 和 mouse 也是一個變數。
ES5:
var data = $('body').data(), // data has properties house and mouse house = data.house, mouse = data.mouse;
以及在node.js中用ES5是這樣:
var jsonMiddleware = require('body-parser').jsonMiddleware ; var body = req.body, // body has username and password username = body.username, password = body.password;
ES6:
var {house,mouse} = $('body').data(); //we'll get house and mouse variables var {jsonMiddleware} = require('body-parser'); var {username,password} = req.body;
在陣列中是這樣的:
var [col1,col2] = $('.column'), [line1,line2,line3, ,line5] = file.split('n');
好處
:使用{}省去了寫物件的屬性的步驟,當然這個{}中的變數是與物件的屬性名字保持一致的情況下。
5.Enhanced Object Literals (增強的物件字面量)
使用物件文字可以做許多讓人意想不到的事情!通過ES6,我們可以把ES5中的JSON變得更加接近於一個類。
下面是一個典型ES5物件文字,裡面有一些方法和屬性: var serviceBase = {port: 3000, url: 'azat.co'}, 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) // Object.create() 方法建立一個擁有指定原型和若干個指定屬性的物件。 var accountServiceES5ObjectCreate = { getAccounts: getAccounts, toString: function() { return JSON.stringify(this.valueOf()); }, getUrl: function() {return "http://" + this.url + ':' + this.port}, valueOf_1_2_3: getAccounts() }
ES6的物件文字中:既可以直接分配getAccounts: getAccounts,也可以只需用一個getAccounts
var serviceBase = {port: 3000, url: 'azat.co'}, getAccount = function(){return [1,2,3]}; var accountService = { __proto__: serviceBase, //通過proto設定屬性 getAccount, // 既可以直接分配getAccounts: getAccounts,也可以只需用一個getAccounts toString() { //這裡將json形式改為函式形式 return JSON.stringify(super.valueOf()); //呼叫super防範 }, getUrl() {return "http://" + this.url + ':' + this.port}, [ 'valueOf_' + getAccounts().join('_') ]: getAccounts()//使用動態key值(valueOf_1_2_3)此處將getAccounts()方法得到的陣列[1,2,3]轉化為字串1_2_3 }; console.log(accountService);
好處
:相當於直接將結果寫進去,而不再必須 key:value
- 將toString: function(){}這種json形式轉變為 toString() {}這樣的函式(類)的形式
- 既可以直接分配getAccounts: getAccounts這樣的json形式,也可以只需用一個getAccounts表達相同的意思
6.Arrow Functions in(箭頭函式)
這些豐富的箭頭是令人驚訝的因為它們將使許多操作變成現實,比如,
以前我們使用閉包,this總是預期之外地產生改變,而箭頭函式的迷人之處在於,現在你的this可以按照你的預期使用了,身處箭頭函式裡面,this還是原來的this。
ES5:
var _this = this; $('.btn').click(function(event){ _this.sendData(); })
ES6: 就不需要用 _this = this:
$('.btn').click((event) =>{ this.sendData(); })
再比如:
ES5:
var logUpperCase = function() { var _this = this;//this = Object {string: "ES6 ROCKS"} console.log('this指的是',this); //Object {string: "ES6 ROCKS"} console.log('_this指的是',_this);//Object {string: "ES6 ROCKS"} this.string = this.string.toUpperCase(); console.log(_this.string); //ES6 ROCKS console.log(this.string);//ES6 ROCKS return function () { return console.log(_this.string); //ES6 ROCKS return console.log(_this.string); //如果return _this.string,將返回 undefined,因為 } } logUpperCase.call({ string: 'ES6 rocks' })();
ES6:我們並不需要用_this浪費時間,現在你的this可以按照你的預期使用了,身處箭頭函式裡面,this還是原來的this
var logUpperCase = function() { this.string = this.string.toUpperCase();//this還是原來的this return () => console.log(this.string); } logUpperCase.call({ string: 'ES6 rocks' })();
注意
只要你願意,在ES6中=>可以混合和匹配老的函式一起使用。當在一行程式碼中用了箭頭函式,它就變成了一個表示式。它將暗地裡返回單個語句的結果。如果你超過了一行,將需要明確使用return。
ES5:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']; var messages = ids.map(function (value) { return "ID is " + value; // explicit return });
ES6:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']; var messages = ids.map((value)=> `ID is ${value}`); //implicit return
好處
:
- 並不需要用_this浪費時間,現在你的this可以按照你的預期使用了,身處箭頭函式裡面,this還是原來的this。
- => 可以代替function關鍵字,當在一行用了箭頭函式,可以省去{},還可以省去return,它會暗地裡返回的。
7.Promises
ES5:
setTimeout(function(){ console.log('Yay!'); }, 1000);
ES6: 我們可以用promise重寫
var wait1000 = new Promise((resolve,reject)=> { setTimeout(resolve,1000); }).then(()=> { console.log('Yay!'); });
如果我們有更多的巢狀邏輯在setTimeout()回撥函式中,好處會明顯一點:
ES5:
setTimeout(function(){ console.log('Yay!'); setTimeout(function(){ console.log('Wheeyee!'); }, 1000) }, 1000);
ES6: 我們可以用promise重寫
var wait1000 = ()=> new Promise((resolve,reject)=>{ setTimeout(resolve,1000);}); wait1000() .then(function(){ console.log('Yay!'); return wait1000() }) .then(function(){ console.log('Wheeyee!'); });
8 Block-Scoped(塊作用域和構造let和const)
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
ES6: 用let限制塊級作用域
function calculateTotalAmount(vip){ var amouont= 0; // probably should also be let, but you can mix var and let if (vip) { let amount = 1; // first amount is still 0 } { // more crazy blocks! let amount = 100; // first amount is still 0 { let amount = 1000; // first amount is still 0 } } return amount; } console.log(calculateTotalAmount(true));//0 因為塊作用域中有了let。
談到const,就更加容易了;它就是一個不變數,也是塊級作用域就像let一樣。
好處
: 我們用let限制塊級作用域。而var是限制函式作用域。
9. Classes (類)
ES6沒有用函式,而是使用原型實現類。我們建立一個類baseModel ,並且在這個類裡定義了一個constructor 和一個 getName()方法:
class baseModel { constructor(options, data) {// class constructor, 注意我們對options 和data使用了預設引數值。 this.name = 'Base'; this.url = 'http://azat.co/api'; this.data = data; this.options = options; } getName() { // class method console.log(`Class name: ${this.name}`); } getUrl() { // class method console.log(`Url: ${this.url}`); } }
AccountModel 從類baseModel 中繼承而來:
class AccountModel extends baseModel { constructor(options, data) { super({private: true}, ['32', '5242']); this.url +='/accounts/'; } get accountsData() { return this.data; } } // 呼叫 let accounts = new AccountModel(5); accounts.getName();// Class name:Base console.log('Data is %s', accounts.accountsData); // Data is 32,5242 //子類必須在constructor方法中呼叫super方法,否則新建例項時會報錯。 //這是因為子類沒有自己的this物件,而是繼承父類的this物件,然後對其進行加工。 //如果不呼叫super方法,子類就得不到this物件。
【注意】:
- 此處的繼承中,子類必須在constructor方法中呼叫super方法,否則新建例項時會報錯。
- 此處的super方法繼承了父類的所有方法,包括不在父類的constructor中的其他方法,當然可以改寫父類方法,比如上述例子,繼承了getName(),getUrl()方法,以及constructor()中的this.name等屬性,同時改寫了this.url,增加了accountsData,且新增的方法前邊要加上get。
- 子類呼叫super方法可以傳入引數,對應constructor()函式的形參。
10. Modules (模組)
ES5匯出:
module.exports = { port: 3000, getAccounts: function() { ... }}
ES6匯出:
export var port = 3000; export function getAccounts(url) { ...}
ES5匯入:
var service = require('module.js'); console.log(service.port); // 3000
ES6匯入:
我們需用import {name} from ‘my-module’語法
import {port, getAccounts} from 'module'; console.log(port); // 300
或者ES6整體匯入:
import * as service from 'module'; console.log(service.port); // 3000
這裡還有許多ES6的其它特性你可能會使用到,排名不分先後:
- 全新的Math, Number, String, Array 和 Object 方法
- 二進位制和八進位制資料型別
- 預設引數不定引數擴充套件運算子
- Symbols符號
- tail呼叫
- Generators (生成器)
- New data structures like Map and Set(新的資料構造對像MAP和set)