你真的懂 == 比較嗎

扌丸著發表於2018-05-23

今天面試回來,像往常一樣開啟手機,看到QQ群上有個加群申請,進群得回答問題:true == '0',看到有個申請的答案為false,然後我就自信的點了拒絕。閒著無聊,開啟電腦在控制檯上輸入題目,結果為false,我就很好奇為什麼是這樣呢?明明兩邊的值都會為true啊,為什麼會錯呢(被拒絕的童鞋不要怪我)。帶這個這個疑問我翻了下你不知道的javascript

javascript中的值分為兩類:

  1. 可以被強制轉化為false的值
  2. 其他(可以被強制轉化為true的值)

我們知道能轉換為false的基本型別有,我們稱其為假值:

  • undefined
  • null
  • ""
  • 0和NaN
  • false

那麼,上面的值既然可以轉化為false,我們的true == '0'兩邊都可以轉化為true,那麼為什麼不相等呢?

我們先來說下寬鬆相等“==”和“===”。在以往的理解中,我的理解一直是:“==”表示兩個值相等,“===”表死兩個值和型別相等。但是書中說,它們的理解應該說是這樣:“==允許在相等比較中進行強制型別轉化,===不允許”,還是不太理解,兩種理解有什麼區別嗎?暫時放一放,我們往後看。。。

下面摘抄一段樹上寫的區別:

根絕第一種解釋,===似乎比==做的事情更多,因為它還要檢查值的型別,第二種解釋中==的工作量更大一些,因為如果值的型別相同海需要進行強制型別轉化。

如果兩個值的型別不同,我們就需要考慮有沒有強制型別轉化的必要,有就用==,否則用===

接下來我們來看幾種比較來加深理解

  1. 字串和數字的比較
var a = 4;
var b = "4";
a == b //true
a === b //false
複製程式碼

這個結果大家應該都知道,但是 == 比較時,是將兩邊的值全部轉化為數字呢還是轉化為字串比較呢?未完待續。。。(皮一下:smile:)

哈哈,開個玩笑,公佈答案:轉化為數字。依據就是:

ES5規範11.9.3.4-5這樣定義(ToNumber強制轉化為數字)
(1)如果Type(x)是數字,Type(y)是字串,則返回x == ToNumber(y)的結果
(2)如果Type(x)是字串,Type(y)是數字,則返回ToNumber == y的結果

  1. 其他型別與布林值比較

我覺得這一塊我們理解的誤區比較多,也是出錯最多的一塊。

例如:

var a = true;
var b = 4;
a == b //false
複製程式碼

以往我們的理解是:數字4是一個真值(與假值對應),會轉化為true,從而兩邊相等。哪裡錯了呢?我們直接來看ES標準

ES5規範11.9.3.6-7這樣定義(ToNumber強制轉化為數字)
(1)如果Type(x)是布林值,則返回ToNumber(x) == y的結果
(2)如果Type(y)是布林值,則返回x == ToNumber(y)的結果

原來比較的時候是將布林值轉化為數字,即:

var a = true;
var b = 4;
var c = true;
var d = "12";
a == b ===>  1 == 4  //false
c == d ===> 1 == "12" ===> 1 == 12  //false
複製程式碼

這樣是不是清楚多了,所以我們判斷的時候別用( a == true)這種判斷。注意:如果x,y中存在 null或undefiend,則參考第三點

  1. null和undefined之間的比較

ES5規範11.9.3.2-3這樣定義
(1)如果x為null,y為undefined,則返回true
(2)如果x為undefined,y為null,則返回true

在 == 中,null和undefined相等,除此之外不存在這種情況

var a = null;
var b;
a == b  //true
a == false //false
b == false //false
a == 0  //false
b == 0 //false
a == ""  //false
b == ""  //false
複製程式碼

今天就寫到這裡,第一次寫文章,如有什麼不對的地方,還望大家指正

相關文章