文章主要梳理了一下,不同類型的值在判斷是否相等時,存在的各種特殊關係,並給出判斷是否相等的可靠方法。
首先說明兩個關係:等於不一定全等,全等則一定等於;不等於則一定不全等,不全等不一定不等於。在文章中,能用全等的地方,等於也是一定成立的;等於不成立的地方,全等也一定不成立,相信大家都能理解,不再作特殊說明。
判斷0的符號
0 === -0,但是它們不完全相同,如何判斷。
先看幾個關係:
Infinity === Infinity // trueInfinity === -Infinity // false1/-0 === -Infinity // true1/0 === Infinity // true
所以有:
1/-0 === 1/-0 // true1/0 === 1/0 // true1/-0 === 1/0 //false
所以,0其實是有符號的,可以使用以上辦法判斷。 判斷undefined和null
還是先看幾組關係:
undefined === undefined // truenull === null // truenull == undefined // truenull === undefined // false
所以,如果只判斷一個變數值是否為null或者變數未定義,只需使用“==”即可,但是如果要清楚地區分null和undefined,那就要進一步比較了。下面是兩個判斷null和undefined的方法:
Object.prototype.toString.call(null) === "[object, Null]"Object.prototype.toString.call(undefined) === "[object, Undefined]"// 還有一個關係注意一下,我看有些面試題會問到:typeof null === "object"typeof undefined === "undefined"
判斷Regex
兩個完全一樣的Regex其實是不相等的:
var a = /[1-9]/;var b = /[1-9]/;a == b // false
因為a,b其實是兩個Regex對象,同樣是參考型別的:
typeof a === "object" // truetypeof b === "object" // true
如果我們希望能夠比較兩個Regex內容是否一樣,而不關心記憶體位址,那麼只需要比較兩個運算式字串是否相等即可:
var a = /[1-9]/;var b = /[1-9]/;'' + a === '' + b // true註:'' + /[1-9]/ === '/[1-9]/'
字串的比較
這裡需要區分字串和字串對象
如果是字串,則直接使用“===”符號判斷即可:
var a = 'a string';var b = 'a string';a === b //true
但是,對於字串對象(參考型別),直接對比時,對比的仍然是記憶體位址:
var a = new String('a string');var b = new String('a string');a == b // false
如果關注字串內容是否相同,則可以將字串對象轉化為字串,再進行比較:
var a = new String('a string');var b = new String('a string');'' + a == '' + b // true// 也可以使用toString方法比較:a.toString() === b.toString() // true
所以,判斷兩個字串內容是否相同,最可靠的辦法是:
function isStringEqual(a, b) { return '' + a === '' + b;}
數位比較
同樣需要區分數值和數值對象:
var a = new Number(5);var b = new Number(5);// 直接對比時不相等a == b //false// 使用+符號,轉化成數值的對比+a === +b //true
但是,有一個特殊的值必須特殊對待,即NaN,它也是Number類型的
Object.prototype.toString.call(NaN) // "[object Number]"typeof NaN // "number"
同時,它的如下關係導致了以上判斷數值是否相等的方法出現了例外:
NaN == NaN //false+NaN == +NaN // false註:+NaN還是NaN
如何在兩個數值都是NaN的情況下判斷兩者是相等的呢。看一個命題:對於任意非NaN的數值對象或數值(a),+a === +a始終成立,假如該等式不成立,則a即為NaN。所以,如果已知a為NaN,如何在b也是NaN時,希望判斷兩者是相等的呢。
if(+a !== +a) return +b !== +b;
解釋如下:
假設a為NaN,判斷條件成立,如果b也是NaN,返回語句的運算式成立,返回true,表示兩者相等(都是NaN);如果b不是NaN,返回語句的運算式不成立,返回false,表示兩者不相等。
將以上判斷的邏輯整合為一個判斷函數,即:
function isNumberEqual(a, b) { if (+a !== +a) return +b !== +b; // 處理特殊情況 return +a === +b;}
Date對象對比
對象的對比也不能直接使用等號判斷,我們還是只關心日期值是否相同,所以,將日期轉化為毫秒數值,然後對比數值是否相同
var a = new Date('2017-9-7');var b = new Date('2017-9-7');a == b //false+a === +b //true註:+a的值為1504713600000,即,對應2017.9.7 00:00:00的毫秒數效果和使用getTime()方法對比一樣a.getTime() === b.getTime() // true
布爾值對象的對比
對象不能直接對比,故,將布爾值轉化為數值,然後對比
var a = new Boolean('123');var b = new Boolean('123');a == b //false+a === +b //true// 註: 布爾值為真,前面加“+”,轉化為數值1,為假則轉為0
文中很多對比的方法,其實都可以找到對應的對象方法實現值的對比,本文最主要的還是提醒各位,在對比時,注意區分對比的是值還是對象,如果目的是對比值是否相等,則要進一步轉化。另外,特別注意各類型的值在對比時存在的特殊情況,以及特殊值之間的關係。 >web前端分享群“189394454”免費擷取2018最新web前端學習資料。