多角度對比 ES5與ES6的區別

ES5與ES6的對比不一樣點整理

本文關鍵詞:ES6,javascript,javascript

1.Default Parameters(默認參數)

es6以前,定義默認參數的方法是在一個方法內部定義java

var link = function (height, color, url) {    
    var height = height || 50;
    var color = color || ‘red‘;
    var url = url || ‘https://blog.csdn.net/u011215669‘;
}

es6寫法,簡單粗暴了不少了node

var link = function(height = 50, color = ‘red‘, url = ‘http://azat.co‘) { ... }

2.Template Literals(模板對象)

es6以前定義模版字符串要這樣寫(其中first和last 是變量)jquery

var name = 'Your name is ' + first + ' ' + last + '.';
 var url = 'http://localhost:3000/api/messages/' + id;

es6中使用新的語法${ },就簡單多啦,注意es6中的模版字符串用得是反引號「(位置如圖)es6

這裏寫圖片描述

var name = `Your name is ${first} ${last}. `;
var url = `http://localhost:3000/api/messages/${id}`;

3.Multi-line Strings (多行字符串)

es6以前定義多行字符串要這樣寫編程

var roadPoem = 'Then took the other, as just as fair,'
+ 'And having perhaps the better '
+ '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.';

es6中的模版字符串也能夠輕鬆實現,甚至插入變量也變得很是簡單json

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 (解構賦值)

在es5中是這樣寫的api

var data = $(‘body‘).data(), // data has properties house and mouse
    house = data.house,
    mouse = data.mouse;

在nodejs中是這樣的數組

var jsonMiddleware = require(‘body-parser‘).jsonMiddleware ;
var body = req.body, // body has username and password
   username = body.username,
   password = body.password;

在es6中就簡化了不少promise

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 (加強的對象字面量)

一個典型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.createserviceBase繼承原型的方法:

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()
 }

在ES6的對象文本中,既能夠直接分配getAccounts: getAccounts,也能夠只需用一個getAccounts,此外,咱們在這裏經過__proto__(並非經過’proto’)設置屬性,以下所示:

var serviceBase = {port: 3000, url: ‘azat.co‘},
  getAccounts = function(){return [1,2,3]};
  var accountService = {
      __proto__: serviceBase,
      getAccounts,
      toString() {
       return JSON.stringify((super.valueOf()));
      },
      getUrl() {return "http://" + this.url + ‘:‘ + this.port},
     [ ‘valueOf_‘ + getAccounts().join(‘_‘) ]: getAccounts()
 };
 console.log(accountService)

ES6對象文本對於舊版的對象文原本說是一個很大的進步。

6.Arrow Functions in(箭頭函數)

在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();
 })

一個另外的例子,咱們經過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,咱們並不須要用t_this浪費時間:

var logUpperCase = function() {
   this.string = this.string.toUpperCase();
   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

請注意,這裏用了字符串模板。在箭頭函數中,對於單個參數,括號()是可選的,但當你超過一個參數的時候你就須要他們。在ES5代碼有明確的返回功能:

var ids = [‘5632953c4e345e145fdf2df8‘, ‘563295464e345e145fdf2df9‘];
 var messages = ids.map(function (value, index, list) {
   return ‘ID of ‘ + index + ‘ element is ‘ + value + ‘ ‘; // explicit return
 });

在ES6中有更加嚴謹的版本,參數須要被包含在括號裏而且它是隱式的返回:

var ids = [‘5632953c4e345e145fdf2df8‘,‘563295464e345e145fdf2df9‘];
 var messages = ids.map((value, index, list) => `ID of ${index} element is ${value} `); // implicit return

7. Promises

es6中極爲強大的promise

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!‘);
 });

有人會說:脫褲子放屁,畫蛇添足嘛!

可是:若是咱們有更多的嵌套邏輯在setTimeout()回調函數中,咱們將發現更多好處:

setTimeout(function(){
   console.log(‘Yay!‘);
   setTimeout(function(){
     console.log(‘Wheeyee!‘);
   }, 1000)
 }, 1000);

在ES6中咱們能夠用promises重寫:

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 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

結果將返回1000,這真是一個bug。在ES6中,咱們用let限制塊級做用域。而var是限制函數做用域。

function calculateTotalAmount (vip) {
  var amount = 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

9. Classes (類)in ES6

若是你喜歡面向對象編程(OOP),那麼你將喜好這個特性。之後寫一個類和繼承將變得容易。類的建立和使用真是一件使人頭疼的事情在過去的ES5中,由於沒有一個關鍵字class (它被保留,可是什麼也不能作)。在此之上,大量的繼承模型像pseudo classical, classical, functional 更加增長了混亂,JavaScript 之間的宗教戰爭只會更加火上澆油。用ES5寫一個類,有不少種方法,這裏就先不說了。如今就來看看如何用ES6寫一個類吧。ES6沒有用函數, 而是使用原型實現類。咱們建立一個類baseModel ,而且在這個類裏定義了一個constructor 和一個 getName()方法:

class baseModel {
    constructor(options, data) { // class constructor,node.js 5.6暫時不支持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}`);
     }
 }

注意咱們對options 和data使用了默認參數值。此外方法名也不須要加function關鍵字,並且冒號(:)也不須要了。另一個大的區別就是你不須要分配屬性this。如今設置一個屬性的值,只需簡單的在構造函數中分配。

AccountModel 從類baseModel 中繼承而來:

class AccountModel extends baseModel {
constructor(options, data) {
super({private: true}, [‘32113123123‘, ‘524214691‘]);
this.name = ‘Account Model‘;
this.url +=‘/accounts/‘;
}
get accountsData() { //calculated attribute getter
// … make XHR
return this.data;
}
}

那麼,你如何調用他們呢?它是很是容易的:

let accounts = new AccountModel(5);
accounts.getName();
console.log(‘Data is %s‘, accounts.accountsData);

結果使人驚訝,輸出是:Class name: Account Model Data is 32113123123,524214691

10. Modules (模塊)

衆所周知,在ES6之前JavaScript並不支持本地的模塊。人們想出了AMD,RequireJS,CommonJS以及其它解決方法。如今ES6中能夠用模塊import 和export 操做了。在ES5中,你能夠在 <script></script>中直接寫能夠運行的代碼(簡稱IIFE),或者一些庫像AMD。然而在ES6中,你能夠用export導入你的類。下面舉個例子,在ES5中,module.js有port變量和getAccounts 方法:

module.exports = {
   port: 3000,
   getAccounts: function() {
     ...
   }
 }

在ES5中,main.js須要依賴require(‘module’) 導入module.js:

var service = require(‘module.js‘);
 console.log(service.port); // 3000

但在ES6中,咱們將用export and import。例如,這是咱們用ES6 寫的module.js文件庫:

export var port = 3000;
 export function getAccounts(url) {
   ...
 }

若是用ES6來導入到文件main.js中,咱們需用import {name} from ‘my-module’語法,例如:

import {port, getAccounts} from ‘module‘;
 console.log(port); // 3000

或者咱們能夠在main.js中把整個模塊導入, 並命名爲 service:

import * as service from ‘module‘;
 console.log(service.port); // 3000

這裏還有許多ES6的其它特性你可能會使用到,排名不分前後:

  1. 全新的Math, Number, String, Array 和 Object 方法

  2. 二進制和八進制數據類型

  3. 默認參數不定參數擴展運算符

  4. Symbols符號

  5. tail調用

  6. Generators (生成器)

  7. New data structures like Map and Set(新的數據構造對像MAP和set)

以上就是我在網上收集整理獲得後獲得的幾點總結,但願能對你們的學習有所幫助。

參考資源:
* http://es6.ruanyifeng.com/
* https://blog.csdn.net/changsimeng/article/details/62883952
* https://blog.csdn.net/u012860063/article/details/62218564

相關文章
相關標籤/搜索