ECMAScript 6 掃盲

barretlee發表於2016-07-11

ECMAScript 6 目前基本成為業界標準,它的普及速度比 ES5 要快很多,主要原因是現代瀏覽器對 ES6 的支援相當迅速,尤其是 Chrome 和 Firefox 瀏覽器,已經支援 ES6 中絕大多數的特性。

6c0378f8gw1f5npzp64c0j20p00dw77u

本文譯自 Github 上的一篇文章,目的是對還不太熟悉 ES6 語法的同學做一個簡單的掃盲。

let 允許建立塊級作用域,ES6 推薦在函式中使用 let 定義變數,而非 var

同樣在塊級作用域有效的另一個變數宣告方式是 const,它可以宣告一個常量。ES6 中,const 宣告的常量類似於指標,它指向某個引用,也就是說這個「常量」並非一成不變的,如:

有幾個點需要注意:

  • let 關鍵詞宣告的變數不具備變數提升(hoisting)特性
  • letconst 宣告只在最靠近的一個塊中(花括號內)有效
  • 當使用常量 const 宣告時,請使用大寫變數,如:CAPITAL_CASING
  • const 在宣告時必須被賦值

ES6 中,箭頭函式就是函式的一種簡寫形式,使用括號包裹引數,跟隨一個 =>,緊接著是函式體:

需要注意的是,上面栗子中的 getPrice 箭頭函式採用了簡潔函式體,它不需要reture 語句,下面這個栗子使用的是正常函式體:

當然,箭頭函式不僅僅是讓程式碼變得簡潔,函式中 this 總是繫結總是指向物件自身。具體可以看看下面幾個栗子:

我們經常需要使用一個變數來儲存 this,然後在 growUp 函式中引用:

而使用箭頭函式可以省卻這個麻煩:

這裡 可以閱讀更多 this 在箭頭函式中的詞法特性。

ES6 中允許你對函式引數設定預設值:

Spread / Rest 操作符指的是 ...,具體是 Spread 還是 Rest 需要看上下文語境。

當被用於迭代器中時,它是一個 Spread 操作符:

當被用於函式傳參時,是一個 Rest 操作符:

ES6 允許宣告在物件字面量時使用簡寫語法,來初始化屬性變數和函式的定義方法,並且允許在物件屬性中進行計算操作:

ES6 支援二進位制和八進位制的字面量,通過在數字前面新增 0o 或者 0O 即可將其轉換為二進位制值:

解構可以避免在物件賦值時產生中間變數:

ES6 允許在物件中使用 super 方法:

ES6 中有一種十分簡潔的方法組裝一堆字串和變數。

  • ${ ... } 用來渲染一個變數
  • ` 作為分隔符

for...of 用於遍歷一個迭代器,如陣列:

for...in 用來遍歷物件中的屬性:

ES6 中兩種新的資料結構集:MapWeakMap。事實上每個物件都可以看作是一個Map

一個物件由多個 key-val 對構成,在 Map 中,任何型別都可以作為物件的 key,如:

WeakMap

WeakMap 就是一個 Map,只不過它的所有 key 都是弱引用,意思就是 WeakMap 中的東西垃圾回收時不考慮,使用它不用擔心記憶體洩漏問題。

另一個需要注意的點是,WeakMap 的所有 key 必須是物件。它只有四個方法delete(key),has(key),get(key)set(key, val)

Set 物件是一組不重複的值,重複的值將被忽略,值型別可以是原始型別和引用型別:

可以通過 forEachfor...of 來遍歷 Set 物件:

Set 同樣有 delete()clear() 方法。

WeakSet

類似於 WeakMapWeakSet 物件可以讓你在一個集合中儲存物件的弱引用,在WeakSet 中的物件只允許出現一次:

ES6 中有 class 語法。值得注意是,這裡的 class 不是新的物件繼承模型,它只是原型鏈的語法糖表現形式。

函式中使用 static 關鍵詞定義建構函式的的方法和屬性:

類中的繼承和超集:

extends 允許一個子類繼承父類,需要注意的是,子類的 constructor 函式中需要執行 super() 函式。

當然,你也可以在子類方法中呼叫父類的方法,如 super.parentMethodName()

這裡 閱讀更多關於類的介紹。

有幾點值得注意的是:

  • 類的宣告不會提升(hoisting),如果你要使用某個 Class,那你必須在使用之前定義它,否則會丟擲一個 ReferenceError 的錯誤
  • 在類中定義函式不需要使用 function 關鍵詞

Symbol 是一種新的資料型別,它的值是唯一的,不可變的。ES6 中提出 symbol 的目的是為了生成一個唯一的識別符號,不過你訪問不到這個識別符號:

注意,這裡 Symbol 前面不能使用 new 操作符。

如果它被用作一個物件的屬性,那麼這個屬性會是不可列舉的:

如果要獲取物件 symbol 屬性,需要使用 Object.getOwnPropertySymbols(o)

迭代器允許每次訪問資料集合的一個元素,當指標指向資料集合最後一個元素是,迭代器便會退出。它提供了 next() 函式來遍歷一個序列,這個方法返回一個包含 donevalue 屬性的物件。

ES6 中可以通過 Symbol.iterator 給物件設定預設的遍歷器,無論什麼時候物件需要被遍歷,執行它的 @@iterator 方法便可以返回一個用於獲取值的迭代器。

陣列預設就是一個迭代器:

你可以通過 [Symbol.iterator]() 自定義一個物件的迭代器。

Generator 函式是 ES6 的新特性,它允許一個函式返回的可遍歷物件生成多個值。

在使用中你會看到 * 語法和一個新的關鍵詞 yield:

每次執行 yield 時,返回的值變為迭代器的下一個值。

ES6 對 Promise 有了原生的支援,一個 Promise 是一個等待被非同步執行的物件,當它執行完成後,其狀態會變成 resolved 或者 rejected

每一個 Promise 都有一個 .then 方法,這個方法接受兩個引數,第一個是處理 resolved 狀態的回撥,一個是處理 rejected 狀態的回撥: