还在纠结==和===是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

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