JavaScript终极面试题:null == undefined、[]+{}、{}+{}等结果多少呢?看完遍打通了奇经八脉任何对象的运算都会了

一、等于的原理

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

对象和基本类型比较时调用顺序如下:属性valueOf—>Object.prototype.valueOf—>toString---->Object.prototype.toString

var a = 1;
var obj = {
    
    valueOf: function(){
    
     return "" }, toString: function(){
    
     return '1'}}
obj == a
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
"aabs"-'A' // NaN
"aabs"+'A' // "aabsA"

"0" == [] 为 false
[].toString()后为字符串空,==不具备传递性,===才具备

5.加法

任何变量前面都可用加法,即是做Number的强制转换

+undefined // NaN
+null // 0
+true // 1
+false // 0
+"123" // 123
+1 // 1
+{
    
    } // NaN
+[] // 0
+(new Date('2020-05-27')) // 1590537600000
+(function(){
    
    }) // NaN

猜猜:[]+[]、[]+{}、{}+[]、{}+{}的结果分别是什么?
答案:"" 、"[object Object]"、0、"[object Object][object Object]"
和你想的一样吗?☞答案详解
那么变量相加要遵循什么规则呢?
同样遵循:
1.基本类型相加,有字符串时,是字符串的拼接,返回字符串
1.基本类型相加,无字符串时,是优先Number()再相加,返回数字
3.有引用类型时,优先调valueOf、toString转化为基本类型再按以上两种原则做加法

6.乘除法

乘法

1*undefined // NaN
1*null // 0
1*true // 1
1*false // 0
1*"123" // 123
1*1 // 1
1*{
    
    } // NaN
1*[] // 0
1*(new Date('2020-05-27')) // 1590537600000
1*(function(){
    
    }) // NaN
"2"*[] // 0
({
    
    })*[] // NaN

除法

1/undefined // NaN
1/null // Infinity
1/true // 1
1/false // 0
1/"123" // 1/123
1/1 // 1
1/{
    
    } // NaN
1/[] // Infinity
1/(new Date('2020-05-27')) // 1/1590537600000
1/(function(){
    
    }) // NaN
"2"/[] // Infinity
({
    
    })/[] // NaN

7.减法

1-undefined // NaN
1-null // 1
1-true // 0
1-false // 1
1-"123" // -122
1-1 // 0
1-{
    
    } // NaN
1-[] // 1
1-(new Date('2020-05-27')) // -1590537599999
1-(function(){
    
    }) // NaN
"2"-[] // 2
({
    
    })-[] // NaN
"aabs"-'A' // NaN

8.求余

1%undefined // NaN
1%null // NaN
1%true // 0
1%false // NaN
1%"123" // 1
1%1 // 0
1%{
    
    } // NaN
1%[] // NaN
1%(new Date('2020-05-27')) // 1
1%(function(){
    
    }) // NaN
"2"%[] // NaN
({
    
    })%[] // NaN
"aabs"%'A' // NaN

各种变量Number、toString集合(记住这些都会隐式转换了)

Number如下:

参数 结果
undefined NaN
null +0
boolean true被转换为1,false转换为+0
number 无需转换
string 由字符串解析为数字。例如,”324″被转换为324
Array []为0;[基本类型]为基本类型Number后的值;其他均为NaN
Object NaN

toString或者转字符串结果如下:

参数 结果
undefined “undefined”
null “null”
boolean “true” 或者 “false”
number 数字作为字符串。比如,”1.765″
string 无需转换
Array []为’’;其他,例如:[null,46,{},undefined,new Date(‘2020-05-27’),[]].toString() // “,46,[object Object],Wed May 27 2020 08:00:00 GMT+0800 (中国标准时间),”
Object “[object Object]”

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

猜你喜欢

转载自blog.csdn.net/qq_29510269/article/details/106349773