javascript
33 个 JavaScript 核心概念系列(四): == 与 ===
原文地址:落明的博客,轉載請注明出處!
一、前言
作為一個程序員,我想大家在第一次看到 a = b 的語句時一定是懵逼的。后來才知道 = 在編程語言中是用來賦值的,而不是用來判斷兩個值是否相等。
那該怎么判斷兩個值是否相等呢?在 C 或 java 中,是使用 == 來進行比較,而 JavaScript 就有意思了,除了使用 == , 還加了 === 。
二、區別與選擇
它們有什么區別?
具體的區別就一句話:== 在比較時允許進行強制類型轉換,而 === 不允許。
很多人都擔心 == 做的事情多一些會不會影響比較的速度,說實話,會的,但影響是微秒級別的,完全可以忽略不計。
不難看出,== 像是 === 的一種更深入的擴展,因此,滿足 === 的值一定滿足 ==,反之則不成立。
該如何選擇使用它們?
很多人會建議你堅持使用 === 而不使用 ==, 我認為這是不明智的,有些時候,比如說處理后端返回的數據時,你無法保證對方傳來的值到你進行比較的時候還是預期的那樣,此時我覺得完全在可以適當的使用 == 來進行兼容。
總的來說,當你真的確定進行比較的值是類型相同的,那就使用 ===,否則,除了幾種特殊情況,使用 == 并沒有什么問題 。
三、=== 的比較規則
基本類型值的比較
=== 的比較規則很簡單,對于非對象類型的值,先判斷兩邊的操作數是否是同一類型,如果是,則進行比較,否則,直接返回 false。
但有兩個例外情況:NaN === NaN 和 +0 === -0。
// 不同類型 '12' === 12; // false 'a' === true; // false null === '12' // false null === undefined; // false// 同類型 1 === 1; // true 'a' === 'a'; // true false === false; // true null === null; // true//特殊情況 NaN === NaN; // false +0 === -0 // true 復制代碼引用類型值的比較
對于包含引用類型值的比較,仍然會先判斷兩邊的數據類型,如果只有一個是引用類型值,則直接返回 false,如果兩邊均是引用類型值,則會比較他們的引用地址是否一致。
const a = {m: 'string',n: 12 }; const b = {m: 'string',n: 12 }; const c = 12;a === b; // false a === c ; // falseconst d = a; a === d; // true 復制代碼四、== 的比較規則
一開始說過了,在使用 == 進行比較時,運行對兩邊的操作數進行強制類型轉換,那么問題來了,什么情況下會進行轉換?不同類型的轉換規則又是怎樣?
在 MDN 中有這樣一張表,用來展示不同類型值進行 == 判斷時的轉換規則。
乍一看可能會覺得很亂,但仍然是可以分幾種情況來概括這些情況。
在具體分析之前,建議先閱讀上一篇文章 顯式 (名義) 與 隱式 (鴨子)類型轉換 ,因為上圖中你能看到有諸如 isFalsy()、ToNumber()、ToString()、ToPrimitive 等抽象方法,使用它們只是為了讓大家知道強制轉換的方向和結果,而這些也都是上一篇文章講到的內容。
Undefined 和 Null 與其它類型值的比較
我們看前兩行和前兩列可以發現:它們只和自身及對方相等,與其他類型值比較均返回 false。 ....這個大概就是傳說中的「黑風雙煞」吧!
大家可能會看到 Object 有一個 isFalse() 方法,這個方法是用來判斷參數值是否是假值,這個時候大家可能會有疑問了,對象不是都是真值嗎?
沒錯,document.all 就是一個假值對象,雖然已經被新的 JavaScript 標準廢棄,但你或許會在老的項目中看到它,記住就好。
由于這倆值的特殊性,后面我們說“其他類型”值的時候是排除這倆類型的。
Number 類型值與其他類型值比較
除了上面的黑風雙煞,Number 算是相等比較時的大哥,誰想和它比較,就得先轉成 Number 類型。
Boolean 類型值與其他類型值比較
既然有大哥,肯定得有小弟,而 Boolean 類型值則一馬當先,以身作則,將大哥的原則貫徹到底,堪稱模范小弟!
其他類型值想和 Boolean 值做比較,Boolean 值搖身一變將自己轉成了 Number 類型,哎,你說,別人能怎么辦?!
無論別人怎么說,Boolean 只想做一只安靜的舔狗,無怨無悔,一生一世。
Object 類型值與其他類型值比較
Object 作為 JavaScript 中最會偽裝自己的一種類型,在比較之前誰也摸不透它們的真實身份。也正因為此,它們的日子過得不盡相同。
在進行比較時,JavaScript 國王會通過 toPrimitive() 方法來揭開他們的真面目,最終你會發現,它們的真實身份可能是任意的一種基本類型。
因此,在最終比較時,它們也將以真實身份與其他類型值比較。
String 類型值與其他類型值比較
對于 String 類型值來說,在進行比較時的日子并不好過,畢竟,黑風雙煞惹不起,黑社會說話也得聽,唯一能讓它感受到生活希望的,就是在與 Object 這個變色龍進行比較的時候了。
只有 Object 在 toPrimitive() 后轉為字符串的時候它們可以以字符串的規則進行比較,否則,它們就要面臨黑風雙煞或是黑社會。
五、== 正確的使用方法
github 上有位大神總結了下面這張圖:
我們可以將此當做一份參考。
其實在實際的使用過程中,只要我們避免一些特殊的情況,== 的使用還是安全的。
下面就是七種所謂的特殊情況。
"0" == false; // true -- 暈! false == 0; // true -- 暈! false == ""; // true -- 暈! false == []; // true -- 暈! "" == 0; // true -- 暈! "" == []; // true -- 暈! 0 == []; // true -- 暈! 復制代碼如何避免?兩個原則:
六、最后
檢驗大家成果的時候到了,
總結
以上是生活随笔為你收集整理的33 个 JavaScript 核心概念系列(四): == 与 ===的全部內容,希望文章能夠幫你解決所遇到的問題。