前端開發者不得不知的ES6十大特性


ES6(ECMAScript2015)的出現,無疑給前端開發人員帶來了新的驚喜,它包含了一些很棒的新特性,可以更加方便的實現很多複雜的操作,提高開發人員的效率。

本文主要針對ES6做一個簡要介紹。 主要譯自:  http://webapplog.com/ES6/comment-page-1/。也許你還不知道ES6是什麼, 實際上, 它是一種新的javascript規範。在這個大家都很忙碌的時代,如果你想對ES6有一個快速的瞭解,那麼請繼續往下讀,去了解當今最流行的編程語言JavaScript最新一代的十大特性。

以下是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其它功能,這裏只列出了10條比較常用的特性。

首先回顧一下JavaScript的歷史,不清楚歷史的人,很難理解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

還記得我們以前不得不通過下面方式來定義默認參數:

一切工作都是正常的,直到參數值是0後,就有問題了,因爲在JavaScript中,0表示fasly,它是默認被hard-coded的值,而不能變成參數本身的值。當然,如果你非要用0作爲值,我們可以忽略這一缺陷並且使用邏輯OR就行了!但在ES6,我們可以直接把默認值放在函數申明裏:

順便說一句,這個語法類似於Ruby!

2.Template Literals(模板對象) in ES6

在其它語言中,使用模板和插入值是在字符串裏面輸出變量的一種方式。因此,在ES5,我們可以這樣組合一個字符串:

幸運的是,在ES6中,我們可以使用新的語法$ {NAME},並把它放在反引號裏

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

ES6的多行字符串是一個非常實用的功能。在ES5中,我們不得不使用以下方法來表示多行字符串:

然而在ES6中,僅僅用反引號就可以解決了:

4.Destructuring Assignment (解構賦值)in ES6

解構可能是一個比較難以掌握的概念。先從一個簡單的賦值講起,其中house 和 mouse是key,同時house 和mouse也是一個變量,在ES5中是這樣:

以及在node.js中用ES5是這樣:

在ES6,我們可以使用這些語句代替上面的ES5代碼:

這個同樣也適用於數組,非常讚的用法:

我們可能需要一些時間來習慣解構賦值語法的使用,但是它確實能給我們帶來許多意外的收穫。

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

使用對象文本可以做許多讓人意想不到的事情!通過ES6,我們可以把ES5中的JSON變得更加接近於一個類。

下面是一個典型ES5對象文本,裏面有一些方法和屬性:

如果我們想讓它更有意思,我們可以用Object.create從serviceBase繼承原型的方法:

我們知道,accountServiceES5ObjectCreate 和accountServiceES5 並不是完全一致的,因爲一個對象(accountServiceES5)在__proto__對象中將有下面這些屬性:

圖片1

爲了方便舉例,我們將考慮它們的相似處。所以在ES6的對象文本中,既可以直接分配getAccounts: getAccounts,也可以只需用一個getAccounts,此外,我們在這裏通過__proto__(並不是通過’proto’)設置屬性,如下所示:

另外,我們可以調用super防範,以及使用動態key值(valueOf_1_2_3):

圖片3

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

6.Arrow Functions in(箭頭函數) ES6

這是我迫不及待想講的一個特徵,CoffeeScript 就是因爲它豐富的箭頭函數讓很多開發者喜愛。在ES6中,也有了豐富的箭頭函數。這些豐富的箭頭是令人驚訝的因爲它們將使許多操作變成現實,比如,

以前我們使用閉包,this總是預期之外地產生改變,而箭頭函數的迷人之處在於,現在你的this可以按照你的預期使用了,身處箭頭函數裏面,this還是原來的this。

有了箭頭函數在ES6中, 我們就不必用that = this或 self =  this  或 _this = this  或.bind(this)。例如,下面的代碼用ES5就不是很優雅:

在ES6中就不需要用 _this = this:

不幸的是,ES6委員會決定,以前的function的傳遞方式也是一個很好的方案,所以它們仍然保留了以前的功能。

下面這是一個另外的例子,我們通過call傳遞文本給logUpperCase() 函數在ES5中:

而在ES6,我們並不需要用_this浪費時間:

請注意,只要你願意,在ES6中=>可以混合和匹配老的函數一起使用。當在一行代碼中用了箭頭函數,它就變成了一個表達式。它將暗地裏返回單個語句的結果。如果你超過了一行,將需要明確使用return。

這是用ES5代碼創建一個消息數組:

用ES6是這樣:

請注意,這裏用了字符串模板。

在箭頭函數中,對於單個參數,括號()是可選的,但當你超過一個參數的時候你就需要他們。

在ES5代碼有明確的返回功能:

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

7. Promises in ES6

Promises 是一個有爭議的話題。因此有許多略微不同的promise 實現語法。Q,bluebird,deferred.js,vow, avow, jquery 一些可以列出名字的。也有人說我們不需要promises,僅僅使用異步,生成器,回調等就夠了。但令人高興的是,在ES6中有標準的Promise實現。

下面是一個簡單的用setTimeout()實現的異步延遲加載函數:

在ES6中,我們可以用promise重寫:

或者用ES6的箭頭函數:

到目前爲止,代碼的行數從三行增加到五行,並沒有任何明顯的好處。確實,如果我們有更多的嵌套邏輯在setTimeout()回調函數中,我們將發現更多好處:

在ES6中我們可以用promises重寫:

還是不確信Promises 比普通回調更好?其實我也不確信,我認爲一旦你有回調的想法,那麼就沒有必要額外增加promises的複雜性。

雖然,ES6 有讓人崇拜的Promises 。Promises 是一個有利有弊的回調但是確實是一個好的特性,更多詳細的信息關於promise:Introduction to ES6 Promises.

8.Block-Scoped Constructs Let and Const(塊作用域和構造let和const)

在ES6代碼中,你可能已經看到那熟悉的身影let。在ES6裏let並不是一個花俏的特性,它是更復雜的。Let是一種新的變量申明方式,它允許你把變量作用域控制在塊級裏面。我們用大括號定義代碼塊,在ES5中,塊級作用域起不了任何作用:

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

這個結果將會是0,因爲塊作用域中有了let。如果(amount=1).那麼這個表達式將返回1。談到const,就更加容易了;它就是一個不變量,也是塊級作用域就像let一樣。下面是一個演示,這裏有一堆常量,它們互不影響,因爲它們屬於不同的塊級作用域:

從我個人看來,let 和const使這個語言變複雜了。沒有它們的話,我們只需考慮一種方式,現在有許多種場景需要考慮。

9. Classes (類)in ES6

如果你喜歡面向對象編程(OOP),那麼你將喜愛這個特性。以後寫一個類和繼承將變得跟在facebook上寫一個評論那麼容易。

類的創建和使用真是一件令人頭疼的事情在過去的ES5中,因爲沒有一個關鍵字class (它被保留,但是什麼也不能做)。在此之上,大量的繼承模型像pseudo classicalclassicalfunctional 更加增加了混亂,JavaScript 之間的宗教戰爭只會更加火上澆油。

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

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

AccountModel 從類baseModel 中繼承而來:

爲了調用父級構造函數,可以毫不費力的喚起super()用參數傳遞:

如果你想做些更好玩的,你可以把 accountData 設置成一個屬性:

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

結果令人驚訝,輸出是:

Class name: Account Model

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 方法:

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

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

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

或者我們可以在main.js中把整個模塊導入, 並命名爲 service:

從我個人角度來說,我覺得ES6模塊是讓人困惑的。但可以肯定的事,它們使語言更加靈活了。

並不是所有的瀏覽器都支持ES6模塊,所以你需要使用一些像jspm去支持ES6模塊。

更多的信息和例子關於ES6模塊,請看 this text。不管怎樣,請寫模塊化的JavaScript。

如何使用ES6  (Babel)

ES6已經敲定,但並不是所有的瀏覽器都完全支持,詳見:http://kangax.github.io/compat-table/es6/。要使用ES6,需要一個編譯器例如:babel。你可以把它作爲一個獨立的工具使用,也可以把它放在構建中。grunt,gulp和webpack中都有可以支持babel的插件。

圖片2

這是一個gulp案列,安裝gulp-babel插件:

在gulpfile.js中,定義一個任務build,放入src/app.js,並且編譯它進入構建文件中。

Node.js and ES6

在nodejs中,你可以用構建工具或者獨立的Babel模塊 babel-core 來編譯你的Node.js文件。安裝如下:

然後在node.js中,你可以調用這個函數:

ES6總結

這裏還有許多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)

參考文獻:

  1. ES6 Cheatsheet (FREE PDF)
  2. http://webapplog.com/ES6/comment-page-1/
  3. Understanding ECMAScript 6 by Nicolas Zakas book
  4. http://ES6-features.org/#DateTimeFormatting
  5. IIFE:立刻運行的函數表達式

如果有人讓你推薦前端技術書,請讓他看這個列表 ->《經典前端技術書籍
發佈了14 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章