JavaScript ultimate interview question: What are the results of null == undefined, []+{}, {}+{}, etc.? After reading it all, you can open up the Eight Extraordinary Meridians and be able to perform calculations on any object.

1. The principle of equality

Before the introduction, let’s summarize: There are five basic types of variables in JavaScript: Undefined, Null, Boolean, Number and String; and other object types Array, Function, Date, etc.
==: equal, there are two situations when comparing the contents of the two: 1. The two types are different, and there will be implicit conversion; 2. The two types are the same, and the contents are compared directly. The following principles are followed when implicit conversion is performed
:
1. When both are basic types , and one is a Boolean type , the call is given first Number()to convert the Boolean type to 0/1;
2. When both are basic types , and one is a string and the other is a numeric type , the call is given first. Number()Convert the string into a number;
3. When comparing basic types and reference typesvalueOf() , the object is converted to the basic type first. If the return type is not a basic type, then toString()the method is called, converted to the string type, and then compared;
4. Reference types and When comparing reference types , the addresses of the two references are compared, not that the same reference is different.
5. Special cases, null == undefinedcomparisons with , null, undefined and others are all false
===: three equals, strict equal, first compare the two types, and then compare the two contents.

2. Difference

Summary: There are three types of variables that require Number() for comparison: BooleanObject , Array, Function, Date, etc. that require valueOf() and toString().NumberString

//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]"

3. Examples (with analysis of various operators)

1. Simple type comparison

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. Complex type comparison

Please also pay attention when the reference type overrides valueOf() and toString(). When toString returns a non-basic type and an exception will be generated when compared with the basic type, it will not be compared with the object.

1) Just override valueOf()

不会报错,因为若返回引用类型则继续调原型链上的Object.prototype.toString()方法

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

2) Rewrite valueOf() and toString() to return reference type

和非引用类型比较时,会报错,因为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

When comparing objects with basic types, the calling sequence is as follows: attribute 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 application scenario

if can be seen as a comparison with the Boolean value 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. Misunderstanding

Misunderstanding:

0 == "0"  //true
0 == []   //true
"0" == [] // false
[] == '' // true
'0' == '' //false
"aabs"-'A' // NaN
"aabs"+'A' // "aabsA"

"0" == [] 为 false
The string after [].toString() is empty, == does not have transitivity, only === does

5.Addition

Addition can be used in front of any variable, that is, forced conversion of Number

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

Guess: What are the results of []+[], []+{}, {}+[], {}+{}?
Answer: "", "[object Object]", 0, "[object Object][object Object]"
Is it the same as you thought? ☞Detailed explanation of the answer
So what rules should be followed when adding variables?
It also follows the following:
1. Addition of basic types . If there is a string, it is the concatenation of strings, and the string
1 is returned. Addition of basic types . If there is no string, Number() is used first and then added, and the number
3 is returned. When referencing types , first adjust valueOf and toString to convert them to basic types, and then perform addition according to the above two principles.

6. Multiplication and division

multiplication

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

division

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. Subtraction

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. Seek surplus

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

Various variable Number and toString collections (remember these will be implicitly converted)

Number is as follows:

parameter result
undefined NaN
null +0
boolean true is converted to 1, false is converted to +0
number No conversion required
string Parsed from string to number. For example, "324" is converted to 324
Array [] is 0; [basic type] is the value after the basic type Number; others are NaN
Object NaN

The result of toString or converting to string is as follows:

parameter result
undefined “undefined”
null “null”
boolean "true" or "false"
number Numbers as strings. For example, "1.765"
string No conversion required
Array [] is ''; others, for example: [null,46,{},undefined,new Date('2020-05-27'),[]].toString() // ",46,[object Object], Wed May 27 2020 08:00:00 GMT+0800 (China Standard Time),”
Object “[object Object]”

Reference article:
https://dorey.github.io/JavaScript-Equality-Table/#three-equals

Guess you like

Origin blog.csdn.net/qq_29510269/article/details/106349773