JavaScript 提供兩種相等運(yùn)算符:==和===。
簡(jiǎn)單說茸习,它們的區(qū)別是相等運(yùn)算符(==)比較兩個(gè)值是否相等柔逼,嚴(yán)格相等運(yùn)算符(===)比較它們是否為“同一個(gè)值”。如果兩個(gè)值不是同一類型撵术,嚴(yán)格相等運(yùn)算符(===)直接返回false背率,而相等運(yùn)算符(==)會(huì)將它們轉(zhuǎn)換成同一個(gè)類型,再用嚴(yán)格相等運(yùn)算符進(jìn)行比較。
嚴(yán)格相等運(yùn)算符
嚴(yán)格相等運(yùn)算符的算法如下:
-
不同類型的值
如果兩個(gè)值的類型不同寝姿,直接返回false交排。
1 === "1" // false
true === "true" // false
上面代碼比較數(shù)值的1與字符串的“1”、布爾值的true與字符串"true"饵筑,因?yàn)轭愋筒煌BǎY(jié)果都是false。
-
同一類的原始類型值
同一類型的原始類型的值(數(shù)值根资、字符串架专、布爾值)比較時(shí),值相同就返回true玄帕,值不同就返回false部脚。
1 === 0x1 // true
上面代碼比較十進(jìn)制的1與十六進(jìn)制的1,因?yàn)轭愋秃椭刀枷嗤阄疲祷豻rue委刘。
需要注意的是,NaN與任何值都不相等(包括自身)鹰椒。另外锡移,正0等于負(fù)0。
NaN === NaN // false
+0 === -0 // true
-
復(fù)合類型值
兩個(gè)復(fù)合類型(對(duì)象漆际、數(shù)組淆珊、函數(shù))的數(shù)據(jù)比較時(shí),不是比較它們的值是否相等奸汇,而是比較它們是否指向同一個(gè)地址施符。
{} === {} // false
[] === [] // false
(function () {} === function () {}) // false
上面代碼分別比較兩個(gè)空對(duì)象、兩個(gè)空數(shù)組擂找、兩個(gè)空函數(shù)操刀,結(jié)果都是不相等。原因是對(duì)于復(fù)合類型的值婴洼,嚴(yán)格相等運(yùn)算比較的是骨坑,它們是否引用同一個(gè)內(nèi)存地址,而運(yùn)算符兩邊的空對(duì)象柬采、空數(shù)組欢唾、空函數(shù)的值,都存放在不同的內(nèi)存地址粉捻,結(jié)果當(dāng)然是false礁遣。
如果兩個(gè)變量引用同一個(gè)對(duì)象,則它們相等肩刃。
var v1 = {};
var v2 = v1;
v1 === v2 // true
注意祟霍,對(duì)于兩個(gè)對(duì)象的比較杏头,嚴(yán)格相等運(yùn)算符比較的是地址,而大于或小于運(yùn)算符比較的是值沸呐。
new Date() > new Date() // false
new Date() < new Date() // false
new Date() === new Date() // false
上面的三個(gè)表達(dá)式醇王,前兩個(gè)比較的是值,最后一個(gè)比較的是地址崭添,所以都返回false寓娩。
-
undefined 和 null
undefined和null與自身嚴(yán)格相等。
undefined === undefined // true
null === null // true
由于變量聲明后默認(rèn)值是undefined呼渣,因此兩個(gè)只聲明未賦值的變量是相等的棘伴。
var v1;
var v2;
v1 === v2 // true
-
嚴(yán)格不相等運(yùn)算符
嚴(yán)格相等運(yùn)算符有一個(gè)對(duì)應(yīng)的“嚴(yán)格不相等運(yùn)算符”(!==),它的算法就是先求嚴(yán)格相等運(yùn)算符的結(jié)果屁置,然后返回相反值焊夸。
1 !== '1' // true
相等運(yùn)算符
相等運(yùn)算符用來比較相同類型的數(shù)據(jù)時(shí),與嚴(yán)格相等運(yùn)算符完全一樣蓝角。
比較不同類型的數(shù)據(jù)時(shí)淳地,相等運(yùn)算符會(huì)先將數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換,然后再用嚴(yán)格相等運(yùn)算符比較帅容。類型轉(zhuǎn)換規(guī)則如下。
-
原始類型的值
原始類型的數(shù)據(jù)會(huì)轉(zhuǎn)換成數(shù)值類型再進(jìn)行比較伍伤。
1 == true // true
// 等同于 1 === Number(true)
0 == false // true
// 等同于 0 === Number(false)
2 == true // false
// 等同于 2 === Number(true)
2 == false // false
// 等同于 2 === Number(false)
'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1
'' == 0 // true
// 等同于 Number('') === 0
// 等同于 0 === 0
'' == false // true
// 等同于 Number('') === Number(false)
// 等同于 0 === 0
'1' == true // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1
'\n 123 \t' == 123 // true
// 因?yàn)樽址D(zhuǎn)為數(shù)字時(shí)并徘,省略前置和后置的空格
上面代碼將字符串和布爾值都轉(zhuǎn)為數(shù)值,然后再進(jìn)行比較扰魂。
-
對(duì)象與原始類型值比較
對(duì)象(這里指廣義的對(duì)象麦乞,包括數(shù)組和函數(shù))與原始類型的值比較時(shí),對(duì)象轉(zhuǎn)化成原始類型的值劝评,再進(jìn)行比較姐直。
[1] == 1 // true
// 等同于 Number([1]) == 1
[1] == '1' // true
// 等同于 Number([1]) == Number('1')
[1] == true // true
// 等同于 Number([1]) == Number(true)
上面代碼中,數(shù)組[1]與數(shù)值進(jìn)行比較蒋畜,會(huì)先轉(zhuǎn)成數(shù)值声畏,再進(jìn)行比較;與字符串進(jìn)行比較姻成,會(huì)先轉(zhuǎn)成數(shù)值插龄,然后再與字符串進(jìn)行比較,這時(shí)字符串也會(huì)轉(zhuǎn)成數(shù)值科展;與布爾值進(jìn)行比較均牢,兩個(gè)運(yùn)算子都會(huì)先轉(zhuǎn)成數(shù)值,然后再進(jìn)行比較才睹。
-
undefined 和 null
undefined和null與其他類型的值比較時(shí)徘跪,結(jié)果都為false甘邀,它們互相比較時(shí)結(jié)果為true。
false == null // false
false == undefined // false
0 == null // false
0 == undefined // false
undefined == null // true
絕大多數(shù)情況下垮庐,對(duì)象與undefined和null比較松邪,都返回false。只有在對(duì)象轉(zhuǎn)為原始值得到undefined時(shí)突硝,才會(huì)返回true测摔,這種情況是非常罕見的。
-
相等運(yùn)算符的缺點(diǎn)
相等運(yùn)算符隱藏的類型轉(zhuǎn)換解恰,會(huì)帶來一些違反直覺的結(jié)果锋八。
0 == '' // true
0 == '0' // true
2 == true // false
2 == false // false
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
上面這些表達(dá)式都很容易出錯(cuò),因此不要使用相等運(yùn)算符(==)护盈,最好只使用嚴(yán)格相等運(yùn)算符(===)挟纱。
-
不相等運(yùn)算符
相等運(yùn)算符有一個(gè)對(duì)應(yīng)的“不相等運(yùn)算符”(!=),兩者的運(yùn)算結(jié)果正好相反腐宋。
1 != '1' // false
原文:https://javascript.ruanyifeng.com/grammar/operator.html#toc6