還在糾結==和===是true還是false嗎?看完遍打通了奇蹟八脈任何比較都會了

一、原理

介紹之前先總結下:javascript中變量的類型有五種基本類型Undefined, Null, Boolean, Number和String;和其他對象類型Array, Function, Date等等。
==:等於,兩者內容的比較,有兩種情況:1.兩者type類型不一樣,會存在隱式轉換;2.兩者type類型一樣,直接比較內容
隱式轉換時遵循如下原則:
1.兩者都是基本類型時,有一個是布爾類型時,優先調用Number()將布爾類型轉化爲0/1;
2.兩者都是基本類型時,一個是字符串一個是數字類型時,優先調用Number()將字符串轉化爲數字;
3.基本類型引用類型比較時,優先調用對象的valueOf()轉化爲基本類型,如果返回不是基本類型再調用toString()方法,轉爲字符串類型,再作比較;
4.引用類型引用類型比較時,比較的是兩者的引用的地址,不是同一個引用都不相同。
5.特例,null == undefined,null,undefined和其他做比較都爲false
===:三等於,嚴格等於,先比較兩者的類型,再比較兩者內容。

二、區別

總結:不相同的作比較時需要Number()的變量有Boolean, NumberString三種類型,需要valueOf()和toString()有Object,Array,Function,Date等。

//Nmuber()
Number(true) // 1
Number(false) // 0
Number(1) // 1
Number("1") // 1

//valueOf
({a:'1'}).valueOf() // {a: "1"}
[1,2,3].valueOf() // [1, 2, 3]
(function test(){}).valueOf() // ƒ test(){}
(new Date('2020-05-26')).valueOf() // 1590451200000

// toString
({a:'1'}).toString() // "[object Object]"
[1,2,3].toString() // "1,2,3"
(function test(){}).toString() // "function test(){}"
(new Date('2020-05-26')).toString() // "Tue May 26 2020 08:00:00 GMT+0800 (中國標準時間)"

有引用類型比較時除了Date類型,其餘都用toString轉化爲字符串類型,記住[]的toString爲'';{} toSting爲"[object Object]"

三、實例

1.簡單類型比較

1 == true //true // Number Boolean
2 == true //false
1 == "1"  //true // Number String
[] == ""  //true // Object String
[] == false // true // Object Boolean
[] == 0   //true // Object Number
({}) == "[object Object]" // true
[] == {}  //false
[] == []  //false
{} == {}  //false
null == undefined //true

2.複雜類型比較

當引用類型重寫了valueOf()和toString()時需也別注意,當toString返回的不是基本類型時並且和基本類型比較時會產生異常,和對象比較則不會

1)只重寫valueOf()

不會報錯,因爲若返回引用類型則繼續調原型鏈上的Object.prototype.toString()方法

var a = 1;
var obj = {valueOf: function(){ return {} }}
a == obj // false

2)重寫valueOf()及toString()返回引用類型

和非引用類型比較時,會報錯,因爲toString()爲比較做隱式轉換的最後一道工序

var a = 1;
var obj = {valueOf: function(){ return {} }, toString: function(){ return {}}}
obj == a // Uncaught TypeError: Cannot convert object to primitive valueat <anonymous>:3:5

和引用類型比較時,不會報錯,因爲valueOf()和toString()都沒有調用直接比較的引用地址

var a = 1;
var obj = {valueOf: function(){ return {} }, toString: function(){ return {}}}
obj == {} // false

3.if應用場景

if可以看做與布爾值true的比較

if(true) console.log("true"); //true
if(false) console.log("true");
if(1) console.log("true"); //true
if(0) console.log("true"); 
if(-1) console.log("true"); //true
if("true") console.log("true"); //true
if("1") console.log("true"); //true
if("0") console.log("true"); //true
if("") console.log("true");
if(null) console.log("true");
if(undefined) console.log("true");
if("null") console.log("true"); //true
if("undefined") console.log("true"); //true
if([]) console.log("true"); //true
if({}) console.log("true"); //true
if([0]) console.log("true"); //true
if(NaN) console.log("true");

4.誤區

誤區:

0 == "0"  //true
0 == []   //true
"0" == [] // false
[] == '' // true
'0' == '' //false

"0" == [] 爲 false
[].toString()後爲字符串空,==不具備傳遞性,===才具備

參考文章:
https://dorey.github.io/JavaScript-Equality-Table/#three-equals

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章