還在糾結==和===是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
, Number
和String
三種類型,需要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