Chicken soup

In my opinion, nothing in this world comes out of nowhere without a lot of accumulation and a lot of thinking, things will not be done well. People may not go to school, but they must learn. There are too many able people in this world. So only continuous progress, in order to do not lose. – han han

The preface

We all know that js data type cast includes display and implicit, that in the daily development process, especially in the judgment of conditions, often because of the data type of the display and implicit conversion of judgment conditions do not take effect, thus causing some strange bugs. Veterans who may have worked for five or six years may not be skilled in this area. Therefore, no matter you are new to the workplace or veteran of the workplace, in the case of you and I are ordinary people’s INTELLIGENCE, if you want to dig their own technical depth and breadth, to become an industry expert, the author believes that it is necessary to go through repeated deliberate practice and continuous review to achieve.

Let’s start with two common interview questions

The first line of

null= =0 // false

null > 0 // false
 
null < 0 // false

null> =0 // true
 
null< =0 // true

[undefined] = =false // true

undefined= =false // false[] = =! []// true[] [] = =// false= = {} {}// false{} = =! {}// false[] = =0 // true

[2] = =2 // true

['0'] = =false // true

'0'= =false // true[] = =false // true

[null] = =0 // true
Copy the code

Does the 80% comparison look easy? Are a few of them a little dizzy? That’s all right. Let’s try another one.

The name of the second

var a = ? ; If (a = = 1 & & & & a = = a = = 2 3) {the console. The log (' small kind! '); }Copy the code

Q: When a is equal to what does the if condition hold and print?

This question, if you have a certain understanding and accumulation of implicit conversion, you may soon have ideas to know how to solve, on the contrary, if you do not accumulate, the interviewer asked you, the brain will have a lot of small stars. We’ll find out the answer to that one at the end.

Let’s review the data types of JS

[] == [], {} == {}, [] ==! [], it is estimated that many partners will have questions? So, before debunking these judgments, it’s worth reviewing the basic data types and storage of JS.

Basic data types of js:

  • string
  • boolean
  • number
  • null
  • undefined
  • symbol

There is also a more complex data type: Object

In terms of how data is stored, we can divide data types into value types and reference types. The value types are stored in stack memory, and the addresses of the reference types are stored in stack memory, such as object names, function names, etc., and then pointer to the data stored in heap memory.

A picture

// Basic data type - stack memory let a1 = 123456; // Basic data type - stack memory let a2 = 'abcdef'; // Basic data type - stack memory let a3 = true; // Basic data type - stack memory let a4 = null; // Basic data type - stack memory let a5 = undefined; Let c = [1, 2, 3]; let c = [1, 2, 3]; Let b = {a: 1}; let b = {a: 1};Copy the code

We’ll look at this problem after we review the JS type of storage

[] == []{} == {}

If both sides of the js type conversion are reference types, then the memory address is directly compared (i.e. the address to which the pointer points).

console.log([]==[]) // false, Pointers to different addresses

console.log({} == {}) // false, Pointers to different addresses
Copy the code

Js implicit type conversion rules

ToString is an operation that converts another type to a string type

ToString

To explain the above transformations:

  • Null: Converts to “null”
  • Undefined: change to “undefined”
  • Boolean types: True and false are converted to “true” and “false” respectively
  • Number type: A string converted to a number, for example, 10 to “10” and 1e21 to “1e+21”.
  • Array.prototype.join(); for example, [1, 2,3] is converted to “1,2,3”; an empty Array [] is converted to an empty string; null or undefined is treated as an empty string
  • Ordinary objects: to string is equal to the direct use of the Object. The prototype, the toString (), returns “[Object Object]”

ToNumber

ToNumber is an operation that converts other types to numeric types

To explain the above transformations:

  • Null: Changes to 0
  • Undefined: indicates NaN
  • String: If it is a pure number, it is converted to the corresponding number and the null character is converted to 0. Otherwise, it is treated as a conversion failure and converted to NaN
  • Boolean: True and false are converted to 1 and 0
  • Array: The array is first converted to its original type, ToPrimitive, and then processed according to the original type as described above
  • Object: The object is first converted to its original type, ToPrimitive, and then treated according to the above rules based on the converted original type

ToBoolean

ToBoolean is an operation that converts other types to Booleans

To explain the above transformations:

  • Null: Changes to false
  • Undefined: changes to false
  • “: converts to false
  • NaN: Converts to false
  • 0: converts to false
  • [] : Converts to true
  • {} : converts to true
  • Infinity: Converts to true

Conclusion:

The only false values in js are false, null, undefined, null, 0, and NaN. All other values are true when converted to Boolean.

ToPrimitive

ToPrimitive Refers to the operation of converting an object type (such as an object or array) to a primitive type.

There are two very important conversion principles:

  1. When an object type needs to be converted to a primitive type, it first looks for the valueOf method of the object. If valueOf returns a valueOf the primitive type, ToPrimitive results in that value
  2. If valueOf does not exist or the valueOf method does not return a valueOf the original type, the toString method of the object is attempted, that is, the toString rule of the object is followed, and the return valueOf toString is used as the result of ToPrimitive.

To explain the above transformations:

  • Number([]), the empty array will call valueOf first, but return the array itself, not the original type, so toString will continue to call, the empty string equivalent to Number(“), so the result is “0”.
  • Number([’10’]) equals Number(’10’) and results in 10
  • The valueOf method of obj1 returns the primitive type 100, so ToPrimitive is 100
  • Obj2 has no valueOf, but toString does exist, and returns a primitive type, so Number(obj2) is 102
  • Obj3’s toString method does not return a primitive type and cannot ToPrimitive, so it throws an error.

Summary in one chart

Loose comparison == implicit conversion difference

We usually recommend using congruence to compare data types in the development process to prevent various problems caused by loose equality in implicit conversion.

An equality comparison between Boolean types and other types

  • Whenever a Boolean type is compared, the value of that Boolean type is first converted to a numeric type
  • According to the ToNumber rule for Boolean types, true is converted to 1 and false to 0
false= =0 // true
true= =1 // true
true= =2 // false
Copy the code
const a = 10;
// the a callback is implicitly cast to true
if (a) {
    console.log('Execute callback');
}
Copy the code

Equality comparison of numeric and string types

  • The string type is converted to a number type when the number type and string type are compared for equality
 0= =' ' // true
 1= ='1' // true
Copy the code

An equality comparison between an object type and a primitive type

  • When the object type is compared to the original type for equality, the object type is converted to the original type according to the ToPrimitive rule
 [2] = =2 // true
Copy the code
  • Array [2] is an object type, so the ToPrimitive operation is performed, that is, valueOf is called first and then toString is called. According to the toString operation rules, the result “2” is obtained, and the string “2” is converted to a number when compared with the number 2. So the final result is true.

A special comparative analysis of the first question:

[] = =! []// true
Copy the code
  1. ! [] is the object type, which is set to true! True is false, that is, [] == false
  2. The right-hand side converts to a number of 0, that is, [] == 0
  3. On the left is an object, valueOf() is not a character nor a string, toString() is called, and the empty string is “== 0”
  4. The empty string is converted to a number, i.e. 0 == 0 is true

Let’s go back to the second interview question analysis:

 var a = {
    // Define an attribute to do the accumulation
    i: 1,
    valueOf () {
      return this.i++
    }
 };
 if (a == 1 && a == 2 && a == 3) {
   console.log('Little boy! ');
 }
Copy the code

Of course, if we do not define valueOf, we can also define toString method to meet the above requirements

 var a = {
    // Define an attribute to do the accumulation
    i: 1,
    toString () {
      return this.i++
    }
 };
 if (a == 1 && a == 2 && a == 3) {
   console.log('Little boy! ');
 }
Copy the code

Null, undefined, NaN, and primitive types are compared equally

  • When null, undefined, NaN are compared to the original type for equality, no implicit conversion takes place and the result of the comparison is directly false

Review the first few equivalents of the first interview question:

null= =0 // false

null > 0 // false
 
null < 0 // false

NaN= =NaN // false

undefined= =null // true

null= =null // true

null= =undefined // true
Copy the code

conclusion

  • A center: converts the left and right sides to a number center
  • Two basic points: conversion conditions: 1. Only when the type is different; 2
  • One country, two systems: use one system for null, NaN and undefined, and use another system for others