這可能是你學習ES7遺漏的知識點

descire發表於2018-04-22

小云是一枚還沒有脫髮的程式設計師,最近看到ES熱度這麼高,決定蹭一波熱度。

ES7新增的特性

  • Array.prototype.includes
  • **

**

小云首先看到了ES7中新增的**運算子,心中暗喜:這麼簡單?

  8 ** 3 // 512
  Math.pow(8, 3) // 512
複製程式碼

但是小云喜歡瞎折騰,於是他又敲了下列程式碼:

  2 ** 2 ** 0 // 2
複製程式碼

結果竟然是2,小云帶著疑惑查了查資料,原來**運算子是右結合的:

  (2 ** 2) ** 0 // 1
複製程式碼

小云終於得到了自己預期的結果,而且還發現了底數的前面不能緊跟一元運算子,即使是+也不行。

Array.prototype.includes

Tip: 為什麼這個方法不叫contains呢?因為一些Bug,它被重新命名為includes

接下來,小云開始學習includes方法:

  [1, 2, 1].includes(1) // true
複製程式碼

小云又敲下了之前用來判斷陣列中的元素是否存在的程式碼:

  if ([1, 2, 1].indexOf(1) !== -1) {
    // true
  }
複製程式碼

哇!終於可以擺脫那個令人討厭的!== -1了。

難道這兩個方法僅僅是在返回值上有區別嗎?小云這次決定不再瞎折騰,直接移步ES7文件

數個小時之後,小云要開始他的表演了。

ES標準的相等比較演算法

  • The Abstract Equality Comparison Algorithm (==)
  • The Strict Equality Comparison Algorithm (===)
  • SameValue (Object.is())
  • SameValueZero (暫未提供API)

對於前兩個大家再熟悉不過了,在我剛學JS的時候,只是通過自己長期累積的經驗去區別兩者的差異:

  [1, 2, 3] == '1,2,3' // true
  ['1'] == 1 // true
複製程式碼

以至於遇到上述情況驚歎不已,但是瞭解原理之後,一切變得那麼的簡單。

The Abstract Equality Comparison Algorithm

  • 當型別相同時,特殊性在於NaN, -0, 0。
  NaN == NaN // false
  -0 == 0 // true
複製程式碼
  • 當型別不同時,第一條準則是:null與undefined相等
  • 當型別不同時,第二條準則是:所有的比較最終多會轉化為數值的比較,而它轉化的優先順序是Boolean => Object => String

前面兩條不難理解,通過['1'] == true比較的過程,熟悉一下第三條規則:

  • 將右邊的Boolean型別轉化為Number型別, 轉化為 ['1'] == 1
  • 將左邊的Object型別轉化為原始值,轉化為 '1' == 1
  • 將左邊的String型別轉化為Number型別, 轉化為 1 == 1

這時你再遇到:

  [] == false // true
複製程式碼

是不是很輕鬆就知道結果了。

The Strict Equality Comparison Algorithm

對於這個演算法需要注意的地方是在Number型別的比較上:

  NaN === NaN // false
  -0 === 0 // true
複製程式碼

Tip: 上述方法的分析多是基於ES5.1,在ES6中都有細微的改變,比如加入Symbol的比較。

SameValue

對於熟練使用ES6的小夥伴,多知道Object.is()這個方法:

  Object.is(NaN, NaN) // true
  Object.is(0, -0) // false
複製程式碼

而Object.is內部採用的比較演算法就是SameValue(x, y),而它與 === 的區別也正是這兩種情況。

SameValueZero

但是你在使用es6中有沒有疑惑這種情況:

  const s = new Set()
  s.add(0)
  s.add(NaN)
  s.has(-0) // true
  s.has(NaN) // true
複製程式碼

是不是與上述的三種演算法的表現多不一樣,這就是第四種比較演算法SameValueZero,它與SameValue的區別主要在於0與-0是否相等。

所以你在實踐includes方法時,遇到:

  const a = [0, NaN]
  a.includes(-0) // true
  a.includes(NaN) // true
複製程式碼

就不用大驚小怪了,因為includes內部使用的比較演算法就是SameValueZero。

參考文獻


    喜歡本文的小夥伴們,歡迎關注我的訂閱號超愛敲程式碼,檢視更多內容.

這可能是你學習ES7遺漏的知識點

相關文章