1. 程式人生 > >ES6常用特性

ES6常用特性

typedef function struct family 原型 url 相同 情況下 variables

以下是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

【備註 】這裏只列出了10條比較常用的特性。並不是所有的瀏覽器都支持ES6模塊,所以你需要使用一些像jspm去支持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)

ES6常用特性