欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

还在纠结==和===是true还是false吗?看完遍打通了奇迹八脉任何比较都会了

程序员文章站 2022-06-15 13:48:48
...

一、原理

介绍之前先总结下: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