理清javascript中等於(==)和全等(===)那些糾纏不清的關係

來源:互聯網
上載者:User

文章主要梳理了一下,不同類型的值在判斷是否相等時,存在的各種特殊關係,並給出判斷是否相等的可靠方法。

首先說明兩個關係:等於不一定全等,全等則一定等於;不等於則一定不全等,不全等不一定不等於。在文章中,能用全等的地方,等於也是一定成立的;等於不成立的地方,全等也一定不成立,相信大家都能理解,不再作特殊說明。

判斷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前端學習資料。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.