Jane said

Recently I was a little dizzy by [] + {} and {} + []. I felt I understood it at that time, but I will forget it after a period of time. May not get the principle of the internal operation mechanism, or a half-understanding of the level. So, went to gnaw the basic knowledge of JS again, finally, I found the trick. Since then, JS data type conversion is no longer confused.

The text start

1. Data type of js:

Js data types include primitive types and reference types

Primitive types (7 types) : Number, String, Boolean, undefined, NULL, Symbol, BigInt

Reference type: Object

2. Explicit type conversion

  • Number()

Conversion rules for converting a primitive type to Number:

Boolean: true to 1, false to 0 Symbol: Symbol type cannot be converted to NumberCopy the code

Rules for converting a reference type to Number:

If the method returns a valueOf the primitive type, then the conversion is performed according to the above rules. If the method returns a compound type, then the toString method of the object is called. If the toString method returns a valueOf the primitive type, then the toString method is called. Convert according to the above rules, if not, an error is reported

Through a few cases to deepen the impression:

 Number({a:1}) 
 // valueOf() -> {a:1} -> toString() -> '[object Object]' -> Number('[object Object]')-> NaN
 Number([1.2]) 
 / / the valueOf () - > [1, 2] - > the toString () - > '1, 2' - > Number (' 1, 2) - > NaN
 Number([1])  
 // valueOf() -> [1] -> toString() -> '1' -> Number('1') => 1
 Number([]) 
 // valueOf() -> [] -> toString() -> '' -> Number('') => 0
 Number(function(){}) 
 // valueOf() -> function(){} -> toString() -> 'function(){}' -> Number('function(){}') => NaN
Copy the code
  • String()

Rules for converting a primitive type to String:

Numeric: Converts to a numeric string

String: string

Undefined: converts to ‘undefined’

Null: Converts to ‘null’

Boolean: Convert to ‘true’ or ‘false’

Symbol: Convert to ‘Symbol()’

Rules for converting a reference type to String:

If the result is a primitive type, the toString method is called. If the result returns a primitive type, the valueOf method is called. If the result returns a primitive type, the toString method is called. If the object type is returned, the conversion fails

Through a few cases to deepen the impression:

  var a1 = { b : 1 };
      a1.toString() // '[object Object]'
      console.log(String(a1)) // '[object Object]'

  var a2 = [1.2.3];
      a2.toString() / / '1, 2, 3'
      console.log(String(a2)) / / '1, 2, 3'

  var a3 = function(){};
      a3.toString() // 'function(){}'
      console.log(String(a3)) // 'function(){}'
        
  var a4 = [];
      a4.toString() / /"
      console.log(String(a4)) / /"
Copy the code
  • Boolean()

Converting to Boolean is easier, just remember this:

Undefined: false

Null: false

NaN: false

“‘ : false

0: false

All but those listed above are converted to true

Implicit type conversion

Actions that trigger implicit type conversions: four operations, judgment statements, native calls (console.log and alert methods internally call String methods).

Except for addition (+), all the other operators (-, *, /, %) convert non-number types to Number types

+ : as an arithmetic operator, it converts other types to numeric types through Number(); The + is treated as a String concatenator when one of the two sides is a String, and the other types are converted to strings via String().

   1 + 2 / / 3
    // Both sides are Number types
   1 +' ' / / '1'
    // There are strings, other types are converted to strings
   1+ false / / 1
    // All other types are converted to Number and then added
    1+ null / / 1
     // All other types are converted to Number and then added
    1+ undefined  //NaN
    // All other types are converted to Number and then added
    1 + function(){} //'1function(){}'
    // Reference types are converted to value types and then added according to the value types
    1 + {} //'1[object Object]'
     // Reference types are converted to value types and then added according to the value types
    1 + [] / / '1'
    / / same as above
    1+ [1.2] / / '11, 2'
    / / same as above
    
Copy the code

= = :

NaN is not equal to any value String converts to Number Boolean when comparing String with Number and Boolean converts to Number when comparing other types null and undefined equals when comparing reference types and value types, A reference type is first converted to a value type (internal call toPrimitive). A reference type is compared with a reference type to determine whether it refers to the same referenceCopy the code

Let’s take a look at some bad examples:

[] [] = =//false
    // Reference type comparison, not pointing to the same reference is false[] = =0  // true
    // [] converts to value type '',''== 0, Number('') -> 0, so true! [] = =0 // true
    / /! [] = false; Number(false) -> 0! [] [] = =//true
     / /! [] converts to value type '', false converts to Number(false) -> 0,'' converts to Number(") -> 0, so true{} = =! {}//false
    / /! {} is false, {} converts to value type '[object object]',false converts to Number(false) -> 0,'[object object]' converts to NaN, so false= = {} {}//false
     // Reference type comparison, not pointing to the same reference is false
    
Copy the code

Classic interview questions

    {} + {} //'[obiect Obiect][obiect Obiect]'
    {} + [] / / 0
    [] + {} //[obiect Obiect]
    [] + [] / /"

Copy the code

for{} + {}In Firefox, the result is NaN

5, have to mention the toPrimitive function

ToPrimitive (input,PreferredType): Converts an object to a value type

Symbol.toPrimitive is a built-in Symbol value that exists as a function value attribute of an object and is called when an object is converted to its original value.

ToPrimitive () converts a value of a reference type to an original value, which may be a String or a Number. The conversion rules for converting a reference type to String are the same as those for converting a reference type to Number.

Input is the object to be converted. When input is a raw value, return input directly

PreferredType is the desired type, which can be a string or a value.

unction ToPrimitive(input,PreferredType) {
    var hint = PreferredType || 'default';
 
    // If it is a raw value, return it directly
    if( isPrimitiveType(input)){ 
        return input 
    }
    if(typeof input === 'symbol') {throw new Error('typeError')}if(input instanceof Date){
        hint = 'string'
    }
    if (hint == "number" || hint == 'default') {
      varres = input.valueOf(); ! isPrimitiveType(res) && (res = res.toString());if(isPrimitiveType(res)){
          return res
      }else{
        throw new Error('typeError')}}if (hint == "string") {
        varres = input.toString(); ! isPrimitiveType(res) && (res = res.valueOf());if(isPrimitiveType(res)){
          return res
      }else{
        throw new Error('typeError')}}function isPrimitiveType(input){
        var primitiveType = ['string'.'undefined'.'number'.'boolean'];
        return  (input === null || primitiveType.indexOf(typeofinput) ! = = -1); }}Copy the code