JavaScript中三個(gè)等號(hào)和兩個(gè)等號(hào)你了解多少
引子
眾所周知,用在if條件判斷語(yǔ)句中,js有六種假值:false, null, undefined, '', NAN, 0。先來(lái)看幾個(gè)例子:
[] === [] NaN === NaN NaN == NaN 0 == [] '' == [] '' == {} [] == undefined {} == [] null == undefined
以上這些判斷結(jié)果是什么,大家能否一看就知道結(jié)果呢?筆者以前對(duì)==和===都只有大概的印象,相信大家也都知道,== 判斷如果兩邊變量的類(lèi)型不同,會(huì)將其先做類(lèi)型轉(zhuǎn)換再作判斷,而 === 則不做類(lèi)型轉(zhuǎn)換,如果類(lèi)型不同,就一定返回 false。但是筆者最近看到了一個(gè)題目,感覺(jué)很有意思,貼出來(lái)給大家看看:
var x = 1; var obj = { valueOf: function(){ x = 2; return 0 } } console.log(obj == 0, x)
恩,這段代碼輸出的結(jié)果是 true, 2,是不是不可思議?還有~
var x = 1; var obj = { valueOf: function(){ return {} }, toString: function(){ return {} } } console.log(obj == 0)
這段代碼直接拋出了異常: Uncaught TypeError: Cannot convert object to primitive value。
如果你和我一樣覺(jué)得很奇怪,那就繼續(xù)往下看吧~
===
的規(guī)則
這個(gè)比較簡(jiǎn)單,我把規(guī)則羅列一下
- 如果類(lèi)型不同,就不相等
- 如果兩個(gè)都是數(shù)值,并且是同一個(gè)值,那么相等,例外的是,如果其中至少一個(gè)是NaN,那么不相等。(判斷一個(gè)值是否是 NaN,只能用isNaN() 來(lái)判斷)
- 如果兩個(gè)都是字符串,每個(gè)位置的字符都一樣,那么相等;否則不相等。
- 如果兩個(gè)值都是true,或者都是false,那么相等。
- 如果兩個(gè)值都引用同一個(gè)對(duì)象或函數(shù),那么相等;否則不相等。
- 如果兩個(gè)值都是null,或者都是undefined,那么相等。
這里不難發(fā)現(xiàn),復(fù)合類(lèi)型的數(shù)據(jù)(比如對(duì)象、數(shù)組、函數(shù)等)之間的比較不是比較他們的值是否相等,而是比較他們引用的對(duì)象是否一樣,因此也不難明白,為什么 [] === [] 判斷為false了。
比如:
==
探究
看下 == 的規(guī)則
- 如果兩個(gè)值類(lèi)型相同,進(jìn)行 === 比較。
- 如果兩個(gè)值類(lèi)型不同,他們可能相等。根據(jù)下面規(guī)則進(jìn)行類(lèi)型轉(zhuǎn)換再比較:
- 如果一個(gè)是null、一個(gè)是undefined,那么相等。
- 如果一個(gè)是字符串,一個(gè)是數(shù)值,把字符串轉(zhuǎn)換成數(shù)值再進(jìn)行比較。
- 如果任一值是 true,把它轉(zhuǎn)換成 1 再比較;如果任一值是 false,把它轉(zhuǎn)換成 0 再比較。
- 如果一個(gè)是對(duì)象,另一個(gè)是數(shù)值或字符串,把對(duì)象轉(zhuǎn)換成基礎(chǔ)類(lèi)型的值再比較。對(duì)象轉(zhuǎn)換成基礎(chǔ)類(lèi)型,利用它的toString或者valueOf方法。 js核心內(nèi)置類(lèi),會(huì)嘗試valueOf先于toString。例外的是Date,Date利用的是toString轉(zhuǎn)換。非js核心的對(duì)象,會(huì)比較麻煩,有興趣的同學(xué)可以研究一下
- 任何其他組合,都不相等。
看到這里,第六條,我們就可以明白,為什么上面的代碼會(huì)輸出意想不到的結(jié)果甚至拋出錯(cuò)誤了。
再來(lái)看一題:
if (x == 10) x += 5
根據(jù)上面的規(guī)則,試想一下,如果我們輸入的x是字符串20,那么x的結(jié)果會(huì)變成什么樣?沒(méi)錯(cuò),就是205,而往往這種情況我們的目的是想計(jì)算20+5的值。
綜合上面的例子,不難看出,== 的比較看似會(huì)比較方便,比如 1 == '1' ,但是會(huì)埋下隱患,比如可能對(duì)類(lèi)型做出錯(cuò)誤的假設(shè)。因此大多數(shù)人建議我們少用== 而盡量使用 ===,事實(shí)上我也推薦如果明確知道類(lèi)型,還是最好用===。
再舉個(gè)簡(jiǎn)單的例子:團(tuán)隊(duì)協(xié)作中你肯定需要讀別人的代碼。而當(dāng)你看到==時(shí),要判斷清楚作者的代碼意圖是確實(shí)需要轉(zhuǎn)型,還是無(wú)所謂要不要轉(zhuǎn)型只是隨手寫(xiě)了,還是不應(yīng)該轉(zhuǎn)型但是寫(xiě)錯(cuò)了……所花費(fèi)的腦力和時(shí)間比明確的===(加上可能需要的明確轉(zhuǎn)型)要多得多。這樣一想,===不要好太多。
明白了==的機(jī)制,那么判斷這6個(gè)假值,就變得容易了。
簡(jiǎn)單看看幾個(gè)例子,大家看看是真是假~
false == '' false == [] 0 == [] '' == [] [] == [] [] == {} null == undefined false == undefined
總結(jié)
可以用一張圖來(lái)表達(dá) == 返回true的幾個(gè)假值:
一、首先看雙等號(hào)前后有沒(méi)有NaN,如果存在NaN,一律返回false。
二、再看雙等號(hào)前后有沒(méi)有布爾,有布爾就將布爾轉(zhuǎn)換為數(shù)字。(false是0,true是1)
三、接著看雙等號(hào)前后有沒(méi)有字符串, 有三種情況:
- 對(duì)方是對(duì)象,對(duì)象使用toString()或者valueOf()進(jìn)行轉(zhuǎn)換;
- 對(duì)方是數(shù)字,字符串轉(zhuǎn)數(shù)字;
- 對(duì)方是字符串,直接比較;
- 其他返回false
- 如果是數(shù)字,對(duì)方是對(duì)象,對(duì)象取valueOf()或者toString()進(jìn)行比較, 其他一律返回false
- null, undefined不會(huì)進(jìn)行類(lèi)型轉(zhuǎn)換, 但它們倆相等
后記
我的建議是:如果你的的確確知道你在做什么(了解類(lèi)型轉(zhuǎn)換的結(jié)果),可以用==;否則還是用===吧。
在網(wǎng)上無(wú)意中看到的圖,大家可以參考看看:
==號(hào)
===號(hào)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 淺析Javascript中雙等號(hào)(==)隱性轉(zhuǎn)換機(jī)制
- 細(xì)數(shù)JavaScript 一個(gè)等號(hào),兩個(gè)等號(hào),三個(gè)等號(hào)的區(qū)別
- JavaScript中三個(gè)等號(hào)和兩個(gè)等號(hào)的區(qū)別(== 和 ===)淺析
- 詳解JavaScript中雙等號(hào)引起的隱性類(lèi)型轉(zhuǎn)換
- javascript等號(hào)運(yùn)算符使用詳解
- javascript中的=等號(hào)個(gè)數(shù)問(wèn)題兩個(gè)跟三個(gè)有什么區(qū)別
- 淺析js中2個(gè)等號(hào)與3個(gè)等號(hào)的區(qū)別
- javascript 全等號(hào)運(yùn)算符使用說(shuō)明
- 淺談JavaScript中等號(hào)、雙等號(hào)、 三等號(hào)的區(qū)別
相關(guān)文章
element-ui?實(shí)現(xiàn)輸入框下拉樹(shù)組件功能
這篇文章主要介紹了element-ui?實(shí)現(xiàn)輸入框下拉樹(shù)組件功能,使用element-ui的?el-input,el-tree,el-popover組件組合封裝,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-05-05javascript實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)特效
下面給大家匯總的幾個(gè)javascript實(shí)現(xiàn)的分頁(yè)代碼,當(dāng)然必須要結(jié)合后臺(tái)代碼實(shí)現(xiàn)。大家可以自行分析一下代碼,希望能夠給大家?guī)?lái)一定的幫助2015-08-08Javascript 獲取字符串字節(jié)數(shù)的多種方法
Javascript 字符串字節(jié)數(shù)獲取功能多種方法2009-06-06javascript使用正則獲取url上的某個(gè)參數(shù)
使用indexOf取得?之后的參數(shù),以&使split進(jìn)行分割成數(shù)組,下面展示了一個(gè)從url上獲取名為MenuCode參數(shù)的過(guò)程2014-09-09寫(xiě)了幾個(gè)類(lèi),希望對(duì)大家有用。
寫(xiě)了幾個(gè)類(lèi),希望對(duì)大家有用。...2006-12-12用roll.js實(shí)現(xiàn)的圖片自動(dòng)滾動(dòng)+鼠標(biāo)觸動(dòng)的特效
用roll.js實(shí)現(xiàn)的圖片自動(dòng)滾動(dòng)+鼠標(biāo)觸動(dòng)的特效...2007-03-03