必須掌握的ES6新特性


ES6(ECMAScript2015)的出現,讓前端開發者收到一份驚喜,它簡潔的新語法、強大的新特性,帶給我們更便捷和順暢的編碼體驗,贊!

 

以下是ES6排名前十的最佳特性列表(排名不分先后):

1、Default Parameters(默認參數) in ES6
2、Template Literals (模板文本)in ES6
3、Multi-line Strings (多行字符串)in ES6
4、Destructuring Assignment (解構賦值)in ES6
5、Enhanced Object Literals (增強的對象文本)in ES6
6、Arrow Functions (箭頭函數)in ES6
7、Promises in ES6
8、Block-Scoped Constructs Let and Const(塊作用域構造Let and Const)
9、Classes(類) in ES6
10、Modules(模塊) in ES6

 

接下來,我們就來學習這十個最經典和實用的ES6新特性。

 

1.Default Parameters(默認參數) in ES6

//ES5我們這樣定義默認參數
var
link = function (height, color, url) { var height = height || 50; var color = color || 'red'; var url = url || 'http://azat.co'; ... }

 

這樣做是有一點小問題的,當默認參數為0時就暴露問題了,因為在JavaScript中,0表示false。

// 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的字符串遠不用如此麻煩,我們可以在反引號(~符的unshift鍵)中使用新語法 ${變量名稱} 表示。

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

 

 

3.Multi-line Strings (多行字符串)in 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

這是一個比較難掌握的知識點,我們先用比較簡單的例子切入。

 

下面這些情況都是很常見的:

//ES5中獲取data對象中的屬性
var
data = response.data, // data has properties info and imageLink info = data.info, imageLink = data.imageLink
//ES5獲取一個模塊中的方法
var
stringHandle = require('toolModule').stringHandle ;

 

ES6中,我們可以使用解構處理以上兩種情況:

var {info, imageLink} = response.data; var {stringHandle} = require('toolModule')

右側的response.data和require('toolModule')都是對象,與左側的 { } 格式相同,首先要保證這一點。個人理解{info, imageLink} = response.data像是{info, imageLink} = {response.data.info, response.data.imageLink}這樣一個對應關系,然后我們就可以直接使用info和imageLink這兩個變量了。

解構還有很多高級用法和用途,深入學習請戳 http://es6.ruanyifeng.com/#docs/destructuring 

 

 

5.Enhanced Object Literals (增強的對象字面量)in ES6

下面是一個典型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) 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(); })

 

關於箭頭函數,我們這里簡單說明即可,因為之前的一篇文章詳細說過這個新特性,想深入學習的請戳 http://www.cnblogs.com/Double-Zhang/p/5441703.html

 

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; } { 
    var amount = 100; { var amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));    // 1000,最后定義的生效,塊級作用域無作用

 

塊級作用域中let定義的變量,只在此塊級作用域中生效,外層無法訪問。

function calculateTotalAmount (vip) { var amount = 0; 
  if (vip) { let amount = 1; 
 } { 
    let amount = 100; 
 { let amount = 1000; 
 } } return amount; } console.log(calculateTotalAmount(true));  // 0,用let定義的變量都不可被最外層訪問

這里簡單提一下,假如if句改為 if( vip ){ amount = 1 } ,那么結果是1,因為這樣相當於定義了一個全局變量。

 

我們知道,const用於聲明常量,同一常量只可聲明一次,聲明后不可修改,而下面的代碼中對於同一常量聲明了多次,卻沒有報錯,原因就是每個常量都只屬於它所在的塊級作用域,互不影響。

function calculateTotalAmount (vip) { const amount = 0; if (vip) { const amount = 1; } { 
    const amount = 100 ; { const amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));  // 0

 

 

9. Classes (類)in ES6

現在就來看看如何用ES6寫一個類吧。ES6沒有用函數, 而是使用原型實現類。我們創建一個類baseModel ,並且在這個類里定義了一個constructor 和一個 getName()方法:

class baseModel { 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}`); } }

 

AccountModel 從類baseModel 中繼承而來:

class AccountModel extends baseModel { constructor(options, data) {     //為了調用父級構造函數,可用super()參數傳遞:
    super({private: true}, ['32113123123', '524214691']); //call the parent method with super
       this.name = 'Account Model'; this.url +='/accounts/'; } // 可以把 accountData 設置成一個屬性:
  get accountsData() { //calculated attribute getter
     return this.data; } } ----------------------

let accounts = new AccountModel(5); accounts.getName(); //Class name: Account Model console.log('Data is %s', accounts.accountsData); //Data is 32113123123,524214691

 

 

10. Modules (模塊)in ES6

眾所周知,在ES6以前JavaScript並不支持本地的模塊。人們想出了AMD,RequireJS,CommonJS以及其它解決方法。現在ES6中可以用模塊import 和export 操作了。

在ES5中,你可以在 <script>中直接寫可以運行的代碼(簡稱IIFE),或者一些庫像AMD。然而在ES6中,你可以用export導入你的類。下面舉個例子,在ES5中,module.js有port變量和getAccounts 方法:

// dev.js文件
module.exports = { port: 3000, getAccounts: function() { ... } }

 

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

var service = require('dev.js'); console.log(service.port); // 3000

 

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

// dev.js文件
export var port = 3000; export function getAccounts(url) { ... }

 

如果用ES6來導入到文件中,我們需用import {name} from ‘my-module’語法,例如:

import {port, getAccounts} from 'dev'; console.log(port); // 3000

 

或者我們可以在文件中把整個模塊導入, 並命名為 service:

import * as service from 'dev'; console.log(service.port); // 3000

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM