[] == ![],走進==隱式轉換的世界

辛月發表於2019-05-25

先來公佈答案:console.log([] == ![]) // true,是不是很酷。==還有個好兄弟——===,下面就來看看哥倆到底幹了啥...

==的執行機制

==運算子為確定兩個運算數是否相等,會對左右兩邊運算數進行型別轉換。

執行型別轉換的規則

  1. 如果一個運算數是Boolean值,在檢查相等性之前,把它轉化成數字值。false轉化成0,true轉換為1。
  2. 如果一個運算數是字串,另一個是數字,在檢查相等性之前,要嘗試把字串轉換成數字。
  3. 如果一個運算數是物件,另一個是字串,在檢查相等性之前,要嘗試把物件轉換成字串。
  4. 如果一個運算數是物件,另一個是數字,在檢查相等性之前,要嘗試把物件轉換成數字。

遵守規則

  1. 值null和undefined相等。
  2. 在檢查相等性時,不能把null和undefined轉換成其他值。
  3. 如果某個運算數是NaN,等號將返回false,非等號將返回true。
  4. 如果兩個運算都是物件,那麼比較它們的引用值。如果兩個運算數指向同一個物件,那麼符號返回true,否則兩個運算數不等。

===的執行機制

  1. 如果型別不同,就[不相等]
  2. 如果兩個都是數值,並且是同一個值,那麼[相等];例外的是,如果其中至少一個是NaN,那麼[不相等]。(判斷一個值是否是NaN,只能用isNaN()來判斷)
  3. 如果兩個都是字串,每個位置的字元都一樣,那麼[相等];否則[不相等]。
  4. 如果兩個值都是true,或者都是false,那麼[相等]。
  5. 如果兩個值都引用同一個物件或函式,那麼[相等];否則[不相等]。
  6. 如果兩個值都是null,或者都是undefined,那麼[相等]。

回頭來驗證一下[] == ![]
第一步:根據運算子的優先順序,!先執行,[]是一個物件,所以![]轉化為false
第二步:根據型別轉換規則第一條——"如果一個運算數是Boolean值,在檢查相等性之前,把它轉化成數字值。false轉化成0,true轉換為1。"。所以false轉換成0==右邊得到0
第三步:根據型別轉換規則第三條——"如果一個運算數是物件,另一個是字串,在檢查相等性之前,要嘗試把物件轉換成字串。"。左邊的[]呼叫toString(),轉換成空字串''
第四步:根據型別轉換規則第二條——"如果一個運算數是字串,另一個是數字,在檢查相等性之前,要嘗試把字串轉換成數字。"。''轉化成0。(左邊得到0
第五步:比較兩邊大小0==0,因此結果為true

總結

轉化規則那麼多,鬼能記得住啊,總結一下,分兩類去記就好:

  1. 原始型別(undefined、null、number、boolean、string)的比較。轉成數字的優先順序最高,也就是說一方出現數字,另一方也要轉成數字比較。
  2. 原始型別和物件(引用)型別的比較。如果一個是物件,另一個是數值或字串,把物件轉換成基礎(原始)型別的值再比較。物件轉換成基礎型別,利用它的object.toString()或者object.valueOf()方法。

補充一點:雖然=====是比較運算子,但它只是結果返回Boolean值,轉化到最後比較的一定不是倆個Boolean值。

相關文章