javascript中的相等操作符(==與===區(qū)別)
1.前言
我們在編程的過程中,經(jīng)常會(huì)遇到判斷兩個(gè)變量是否相等的情況,ECMAscript提供了兩種相等操作符”==”和”===”來判斷,這兩種操作都會(huì)返回一個(gè)boolean值。一般來說,我們把”==”稱之為相等,稱”===”為全等。當(dāng)兩相比較的兩個(gè)變量數(shù)據(jù)類型一致時(shí),情況比較簡單,而當(dāng)操作符兩邊的變量類型不一致,甚至其中的某個(gè)變量是對象時(shí),情況就比較復(fù)雜了,下面分別介紹當(dāng)操作數(shù)類型不同時(shí)運(yùn)算結(jié)果會(huì)怎么樣。
2.全等操作符 “===”
全等操作符”===”的情況相對來說比較簡單。當(dāng)用全等操作符”===”來判斷時(shí),首先檢查操作符兩邊操作數(shù)數(shù)據(jù)類型是否一致,若不一致,則直接返回false,否則,才進(jìn)行下一步判斷。如果是兩個(gè)boolean的比較,則”===”兩邊必須同為true或同為false,才可以返回true,否則返回false.若兩相比較的是數(shù)字,那么只有當(dāng)這兩個(gè)數(shù)字大小相等時(shí)才會(huì)返回true,否則返回false。如果要比較的兩個(gè)變量是字符串,先比較兩個(gè)字符串的長度length是否相等,如果長度不一樣,則返回false,如果相等,則從兩個(gè)變量的第一個(gè)字符開始比較是否相等,一直比較到最后一位,如果其中的某一位不想等,則返回false,否則返回true,(注意:字符串的比較是不會(huì)忽略空格的,所以在比較兩個(gè)字符串是否相等時(shí),為確保安全,應(yīng)該先去除空格,然后把兩個(gè)字符串同轉(zhuǎn)為大寫或者小寫之后再進(jìn)行比較)。而null只有在null===null的情況下才會(huì)返回true,其它情況都返回false,同樣,undefined只有在undefined===undefined的情況下才會(huì)返回true,否則返回false。如:
true === 1 //false "1" === 1 //false //boolean的比較 true === true //true true === false //false //string的比較 "hello" === "helloworrld" //false "hello" === "world" //false "hello" === " hello" //false "hello" === "hellO" //false "hello" === "hello" //true //number的比較 1 === 1 //true 1 === 1.0 //true 1 === 1.2 //false //null和undefined的比較 undefined === undefined //true null === null //true undefined === null //false,兩者在"=="時(shí)才返回true
如果進(jìn)行”===”比較的兩個(gè)操作數(shù)不是基本類型值,而是兩個(gè)對象,這時(shí)候判斷依據(jù)就是,判斷這兩個(gè)變量是否是”同一個(gè)”對象
var a,b,c; a = b = { name : '柳輕侯', city : '南京' }; c = { name : '柳輕侯', city : '南京' }; a === b //true a === c //false
兩個(gè)對象僅僅”長得一樣”是不夠的,a和c都是Object實(shí)例,且兩者擁有相同的屬性和值,可是這兩個(gè)卻不是”同一個(gè)”對象,因?yàn)閷?shí)際上a和c指向了兩個(gè)不同的實(shí)例,所以這兩個(gè)對象是不全等的。而a和b卻是指向了同一個(gè)對象,換個(gè)說法,a和b是同一個(gè)對象的不同別名,他們實(shí)際上指向的對象是完全相同的,所以a === b?!?==” 與 “===” 比較規(guī)則一樣,在此不再贅述。
3.相等操作符”==”
全等操作符在進(jìn)行判斷的時(shí)候,如果兩個(gè)變量的類型不同,則直接返回false,而與此不同,”==”相等操作符在判斷的時(shí)候,如果兩個(gè)變量的類型不同,則會(huì)做一個(gè)隱式的類型轉(zhuǎn)換,把要比較的兩個(gè)值轉(zhuǎn)化為相同的類型再做比較,那么這種轉(zhuǎn)化規(guī)則是怎么樣的?
在轉(zhuǎn)化不同數(shù)據(jù)類型時(shí),相等和不等操作符遵循下面的基本規(guī)則
- 如果其中一個(gè)操作數(shù)是是boolean值,則在比較之前會(huì)先將boolean值轉(zhuǎn)化為number值,true轉(zhuǎn)化為1,false轉(zhuǎn)為0;
- 如果其中一個(gè)操作數(shù)是string類型,而另一個(gè)是number類型,則在比較之前先將string類型轉(zhuǎn)化為number類型再進(jìn)行判斷;
- 在比較之前,undefined和null是不會(huì)轉(zhuǎn)為其他值進(jìn)行比較的;
- 如果其中一個(gè)操作數(shù)是對象,而另一個(gè)是基本類型值,則在比較之前先將對象轉(zhuǎn)為基本類型值,然后再依據(jù)前面的規(guī)則進(jìn)行后續(xù)的比較;
兩個(gè)操作數(shù)在比較時(shí)遵循下列規(guī)則
- undefined和null是相等的,即:undefined == null;
- 如果有一個(gè)操作數(shù)是NaN,那么返回false,即使兩個(gè)操作數(shù)都是NaN,也會(huì)返回false;
- 如果兩個(gè)操作數(shù)是對象,則比較規(guī)則跟”===”的比較規(guī)則是一樣的,除非這兩個(gè)操作數(shù)是同一個(gè)對象,則返回true,否則返回false;
此處需要注意的是,NaN == NaN是返回false的,NaN意思是 not a number,也就是說該操作數(shù)是一個(gè)非數(shù)字,這個(gè)非數(shù)字是不確定的,它的值是未知的,甚至可能根本就不能用javascript的語法表示出來,這樣一個(gè)未知量是不能用來進(jìn)行特定比較的,兩個(gè)未知的東西,如果不能確定它的值是什么,當(dāng)然不能說 NaN == NaN。那么既然不能用”==”來比較,我們怎么去判定一個(gè)變量是不是NaN呢 ,既然不能用相等來判定,那么不妨反其道而行之,用”!=”來判定,判定一個(gè)變量是否不等于NaN。比如:
//如果需要判定一個(gè)變量是不是NaN,可以如下 //a是你需要判定的變量 if((typeof a === "number") && a != NaN ){ //此處需要注意,NaN也是number類型 //TODO }
4.常見比較情況及其結(jié)果
null == undefined // true "NaN" == NaN // false 5 == NaN // false NaN == NaN // false NaN != NaN // true false == 0 // true true == 1 // true true == 2 // false undefined == 0 // false null == 0 // false "5" == 5 // true
5.典型例題解析
![] == [] //true
這是一道比較容易令人困惑的題,按照正常的思維模式,對一個(gè)操作數(shù)邏輯取反,跟這個(gè)操作數(shù)本身的值是相對的,如果這個(gè)操作數(shù)本身的值是true,那么取反之后就是false,反之,如果這個(gè)操作數(shù)的值是false,那么對其邏輯取反之后就是true,無論如何也不會(huì)是同一個(gè)值,可是事實(shí)上卻是![] == []。首先,![]的值是false,因?yàn)檫@里[]被當(dāng)成了一個(gè)數(shù)組的實(shí)例,是一個(gè)對象,而對象都是真值,對其取反,得到一個(gè)假值,也就是false。其次看等號(hào)右邊,[]是一個(gè)對象,要將其轉(zhuǎn)為基本類型值,會(huì)先調(diào)用數(shù)組的valueOf方法,而數(shù)組的valueOf方法返回?cái)?shù)組本身,沒有得到一個(gè)基本值,這時(shí)候要繼續(xù)調(diào)用數(shù)組的toString方法,得到一個(gè)””空字符串,所以這時(shí)候也就變成了false == “”是否為真的問題了,而根據(jù)前面的規(guī)則,如果有一個(gè)操作數(shù)為boolean值,會(huì)將其轉(zhuǎn)為數(shù)值,false轉(zhuǎn)化為0。進(jìn)而,問題轉(zhuǎn)化為0 == “”是否為真值的問題,當(dāng)number和string比較時(shí),會(huì)將string轉(zhuǎn)為number,而””會(huì)轉(zhuǎn)為0。最后,問題變演化成了0 == 0是否為真值,毋庸置疑,結(jié)果是true。這里要注意的就是![],它被當(dāng)成了一個(gè)整體的邏輯值,是直接對對象進(jìn)行取反,是一個(gè)假值,而不是先把[]轉(zhuǎn)化為基本值再取反
6.小結(jié)
“==”在比較不同類型值得時(shí)候會(huì)進(jìn)行隱式的類型轉(zhuǎn)化,而”===”不會(huì)轉(zhuǎn)化,全等一定相等,相等卻不一定全等,這是一個(gè)充分不必要條件。undefined和null相等而不全等,且在相等比較的時(shí)候不會(huì)轉(zhuǎn)化為其他類型的值。NaN是不等于NaN 的,要判斷某個(gè)變量是不是NaN,要用”!=”。對象和非對象在進(jìn)行比較的時(shí)候會(huì)先轉(zhuǎn)為基本類型值然后再根據(jù)上面的規(guī)則進(jìn)行比較。
7.參考資料
《javascript高級(jí)程序設(shè)計(jì)》
《javascript權(quán)威指南》
- 詳解JavaScript中的Object.is()與"==="運(yùn)算符總結(jié)
- JS中==、===你分清楚了嗎
- 實(shí)例分析JS中的相等性判斷===、 ==和Object.is()
- JavaScript中的"=、==、==="區(qū)別講解
- javaScript中"=="和"==="的區(qū)別詳解
- 詳解js中==與===的區(qū)別
- 淺談JS中的!=、== 、!==、===的用法和區(qū)別
- JavaScript中三個(gè)等號(hào)和兩個(gè)等號(hào)的區(qū)別(== 和 ===)淺析
- JavaScript里 ==與===區(qū)別詳解
- JS不要再到處使用絕對等于運(yùn)算符了
相關(guān)文章
Express框架詳解app函數(shù)使用實(shí)例
這篇文章主要為大家介紹了Express框架app函數(shù)使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03JS指定音頻audio在某個(gè)時(shí)間點(diǎn)進(jìn)行播放
這篇文章主要介紹了JS指定音頻audio在某個(gè)時(shí)間點(diǎn)進(jìn)行播放,獲取當(dāng)前音頻audio的長度,音頻時(shí)長格式轉(zhuǎn)化,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11Firefox getBoxObjectFor getBoundingClientRect聯(lián)系
Firefox在含有flash的網(wǎng)頁上提示:不建議使用 getBoxObjectFor() 。 請使用 element.getBoundingClientRect()。2008-10-10JS中產(chǎn)生標(biāo)識(shí)符方式的演變
本文記錄下JS中產(chǎn)生標(biāo)識(shí)符方式的演變,從ES5到ES6,ES5及其之前是一種方式,只包含兩種聲明(var/function),ES6則增加了一些產(chǎn)生標(biāo)識(shí)符的關(guān)鍵字,如 let、const、class。2015-06-06微信小程序 如何引入外部字體庫iconfont的圖標(biāo)
這篇文章主要為大家詳細(xì)介紹了微信小程序引入外部字體庫iconfont圖標(biāo)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01微信小程序使用第三方庫Immutable.js實(shí)例詳解
Immutable 是 Facebook 開發(fā)的不可變數(shù)據(jù)集合。不可變數(shù)據(jù)一旦創(chuàng)建就不能被修改,是的應(yīng)用開發(fā)更簡單,允許使用函數(shù)式編程技術(shù),比如惰性評(píng)估。微信小程序無法直接使用Immutable.js,下面就來說說微信小程序如何使用第三方庫Immutable.js。2016-09-09JS動(dòng)畫定時(shí)器知識(shí)總結(jié)
這篇文章給大家總結(jié)了關(guān)于JS動(dòng)畫中定時(shí)器的相關(guān)用法以及相關(guān)知識(shí)點(diǎn)總結(jié),有需要的朋友可以參考學(xué)習(xí)下。2018-03-03