首先我們要知道 == 和 === 到底都是什么概念,區(qū)別是什么,才可以在不用的場景中使用這兩個運(yùn)算符。
=== 叫做嚴(yán)格運(yùn)算符, == 叫做相等運(yùn)算符。
嚴(yán)格運(yùn)算符的運(yùn)算規(guī)則如下:
- 如果兩個值的類型不同,直接返回
false。 - 同一類型的原始類型的值(數(shù)值、字符串、布爾值)比較時,值相同就返回
true,值不同就返回false。 - 兩個復(fù)合了類型(對象、數(shù)組、函數(shù))的數(shù)據(jù)比較時,不是比較它們的值是否相等,而是比較它們是否指向同一個對象。
-
undefined和null與自身嚴(yán)格相等。
下面舉幾個例子:
'111' === 111 // false
111 === 111 // true
111 === 222 // false
{a:'1'} === {a:'1'} // false
var a = {value:'1'};
var b = {value:'1'};
a === b; // false
a === a; // true
var c = a;
c === a; // true
null === null // true
undefined === undefined // true
相等運(yùn)算符在比較相同類型的數(shù)據(jù)時,與嚴(yán)格相等運(yùn)算符完全一樣。
在比較不同類型的數(shù)據(jù)時,相等運(yùn)算符會先將數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換,然后再用嚴(yán)格相等運(yùn)算符比較。
類型轉(zhuǎn)換規(guī)則如下:
- 原始類型的數(shù)據(jù)會轉(zhuǎn)換成數(shù)值類型再進(jìn)行比較。字符串和布爾值都會轉(zhuǎn)換成數(shù)值。
- 對象(這里指廣義的對象,包括數(shù)值和函數(shù))與原始類型值比較時,對象轉(zhuǎn)化成原始類型的值,再進(jìn)行比較。
-
undefined和null與其他類型的值比較時,結(jié)果都為false,它們相互比較時結(jié)果為true。
通過上面類型轉(zhuǎn)換規(guī)則的介紹我們可以看出,相等運(yùn)算符隱藏的類型轉(zhuǎn)換,會帶來一個違反直覺的結(jié)果。
下面舉幾個例子:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
甚至還會改變比較的數(shù)據(jù)的值!請看代碼:
var x = 1;
var obj = {
valueOf: function() {
x = 2;
return 0;
}
}
console.log(obj == 0, x); // true, 2
// 根據(jù)類型轉(zhuǎn)換規(guī)則的第二點(diǎn)可知對象與原始類型的值比較時,對象會轉(zhuǎn)化成原始類型的值,再進(jìn)行比較。在對象轉(zhuǎn)化成原始類型的過程中會調(diào)用 obj.valueOf 這個方法所以全局變量 x 會賦值為 2
或者產(chǎn)生異常
var x = 1;
var obj = {
valueOf: function() {
return {}
},
toString: function() {
return {}
}
}
console.log(obj == 0); // Error: Cannot convert object to primitive value
// 中文解釋為 "不能將對象轉(zhuǎn)換為原始值",詳見 http://blog.csdn.net/wopelo/article/details/61913796
由此可見,使用 == 在很多情況下是不安全的,并且可能會造成一些錯誤。這就是為什么建議盡量不要使用相等運(yùn)算符的原因。
那到底什么時候可以使用 == 相等運(yùn)算符呢?
答案:是只有在檢測 null/undefined 的時候可以使用 x == null,因?yàn)槲覀兺ǔ2粎^(qū)分 null 和 undefined ,即將 x == null 作為 x === null || x === undefined 的縮寫。其他時候會建議使用嚴(yán)格運(yùn)算符。
如果非要問還有沒有其他情況可以使用 == 相等運(yùn)算符,這里有一篇文章進(jìn)行了詳細(xì)的介紹,可以參考:
在JavaScript中什么時候使用==是正確的?