【重溫基礎】18.相等性判斷

pingan8787發表於2019-01-22

本文是 重溫基礎 系列文章的第十八篇。 今日感受:優化自己的程式碼,也是很愉快的事情。

系列目錄:

本章節複習的是JS中的關於嚴格相等和非嚴格相等的一些知識。

前置知識:
判斷兩個變數的值是否相等,是程式設計中非常重要的一個操作。這裡我們心裡面先有兩組對照,思考下:

  • 相等 和 不相等
  • 全等 和 不全等

1.介紹

在我們比較字串、數值和布林值的相等性,是比較簡單的,但是到了比較物件的時候,問題就比較複雜。
早期的時候ECMAScript規範中,在判斷相等和不相等時,會先將物件轉換成相似的型別,再執行比較。後面有人質疑其合理性,最後ECMAScript提出解決方法:提供兩組操作符:

  • 相等不相等(寬鬆相等):先轉換再比較,使用==
  • 全等不全等(嚴格相等):僅比較不轉換,使用===

另外還有一類ES6新增的方法:

  • Object.is (ES6新增)

2.相等和不相等

JavaScript中用相等操作符使用==進行比較,若兩個運算元相等,則返回true,否則返回false。反之,不相等操作符使用!=
這兩個操作符都會先轉換運算元型別,再進行比較

通常在轉換不同資料型別時,相等和不相等會遵循以下規則:

  • 若有一個運算元是布林值,則比較前會將布林值轉換為數值false轉為0true轉為1
  • 若一個運算元是字串,另一個是數值,則比較前會將字串轉換為數值
  • 若一個運算元是物件,另一個不是,則比較前會呼叫valueOf()方法,用返回的基本型別值來判斷。

兩個操作符進行比較時會遵循下面規則:

  • nullundefined相等。
  • 比較前不能講nullundefined轉換成其他值。
  • 若一個運算元是NaN,則不相同(==時返回false!=時返回true)。
  • 若兩個運算元是NaN,則不相同(==時返回false!=時返回true)。
  • 若兩個運算元都是物件,則比較它們是不是同一個物件。
  • 若兩個運算元都指向同一個物件,則相等操作符返回true,否則返回false

下面列出一些特殊情況的比較 :

表示式
null == undefined true
"NaN" == NaN false
9 == NaN false
NaN == NaN false
NaN != NaN true
false == 0 true
true == 1 true
true == 2 false
undefined == 0 false
null == 0 false
"9" == 9 true

3.全等和不全等

除了比較前不轉換運算元歪,全等和不全等與相等和不相等並無區別,但使用的是===,只有當不轉換的情況下兩個運算元相同,才會返回true

"99" == 99 ;  // true   因為先轉換型別 number 和 number
"99" === 99 ; // false  因為不轉換型別 string 和 number
複製程式碼

不全等操作符就相對應的使用!==

"99" != 99 ;  // false   因為先轉換型別 number 和 number
"99" !== 99 ; // true    因為不轉換型別 string 和 number
複製程式碼

特殊的:

null == undefined;   // true  類似的值
null === undefined;  // false 型別不同
複製程式碼

由於相等和不相等操作符存在型別轉換問題,因此為了保持程式碼中資料型別的完整性,我們推薦使用去哪等和不全等操作符。

4.同值相等(Object.is

Object.is(value1, value2);,傳入兩個需要對比的值。
Object.is() 判斷兩個值是否相同,並且不會對引數進行型別轉換。如果下列任何一項成立,則兩個值相同:

  • 兩個值都是 undefined
  • 兩個值都是 null
  • 兩個值都是 true 或者都是 false
  • 兩個值是由相同個數的字元按照相同的順序組成的字串
  • 兩個值指向同一個物件
  • 兩個值都是數字並且
    • 都是正零+0
    • 都是負零 -0
    • 都是 NaN
    • 都是除零NaN 外的其它同一個數字
Object.is('leo', 'leo');     // true
Object.is(window, window);   // true

Object.is('leo', 'pingan');     // false
Object.is([], []);           // false

var leo = { a: 1 };
Object.is(leo, leo);       // true

Object.is(null, null);       // true

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

另外還有特殊的:

  • 零值相等:
    與同值相等類似,不過會認為 +0-0 相等。

5.對比圖

相等操作符對於不同型別的值,進行的比較如下圖所示(來源 MDN):

MDN 相等1

注意:

  • ToNumber(A) 表示比較前將引數 A 轉換為數字
  • ToPrimitive(A)通過嘗試呼叫 AA.toString()A.valueOf() 方法,將引數 A 轉換為原始值(Primitive)。

MDN 相等2

MDN 相等3

MDN 相等4

參考文章:

  1. MDN JavaScript 中的相等性判斷
  2. JavaScript高階程式設計

本部分內容到這結束

Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 github.com/pingan8787/…
JS小冊 js.pingan8787.com

歡迎關注我的微信公眾號【前端自習課】

相關文章