There are two types of data types in JavaScript: primitive and object:

Primitive type: Undefined, Null, String, Number, Boolean, Symbol (es6)

Object type: Object

There are three main types of implicit transformations involved:

1. Convert value to original value, ToPrimitive().

2. Convert values to numbers, ToNumber().

Convert the value to a string, ToString().

The value is converted to the original value by ToPrimitive

ToPrimitive, the abstract operation inside the JS engine, has this signature:

ToPrimitive(input, PreferredType?)

Input is the value to be converted, and PreferredType is an optional parameter that can only be of type Number or String. It is just a conversion flag. The converted result does not have to be the type of the parameter value, but the converted result must be a primitive value (or an error).

For Date, the PreferredType is a String and all other objects are numbers.

Conversion of primitive types

Addition, subtraction, multiplication and division:

1. Add a number to a string, and the number becomes a string. Numeric plus number or string plus string does not require conversion.

In the process of addition, the left and right sides of the equal sign are ToPrimitive() operation, and then if there are two or more original values as long as one of them is String type, the two or more original values are converted into String toString() operation, String splicing; Otherwise, two or more original values are converted to the toNumber() operation, adding the numbers.

var a = 1 + 2 + '3';
console.log(a, typeof a); // The result is '33' string

var b = 1 + 2 + 3;
console.log(b, typeof b); // The result is 6 number

var c = '1' + 2 + 3;
console.log(c,typeof c);  // The result is '123' string
Copy the code

2. Subtract a number from a string. The string is converted to a number. NaN is converted if the string is not a pure number. Same thing with strings minus numbers. Subtracting two strings is also converted to numbers first. (NaN belongs to a special type of number.)

var a = 10 - '2';
console.log(a, typeof a);  //8 number

var b = 10 - '2a';  
console.log(b, typeof b);  //NaN number

var c = 10 - 'one';
console.log(c, typeof c);  //NaN number
Copy the code

3. The same goes for multiplication, division, greater than, less than, and subtraction.

var a = '10' * '20';
console.log(a, typeof a);  //200 number

var b = '20' / '10';
console.log(b, typeof b);  //2 number

var c = '10' / 'one';
console.log(c, typeof c);  //NaN number
Copy the code
Implicit conversion of ==

1. The undefined equal to null

2. When comparing a string with a number, the string is converted to a number

3. When a number is compared with a Boolean, the Boolean turns to a number

4. When a string is compared with a Boolean, the two are converted to numbers

console.log([] == null); //false

console.log(null= =0); //false

console.log(undefined= =null);  //true

console.log('0'= =0);  //true, string to number

console.log(0= =false);  //true, Boolean to number

console.log('0'= =false);  //true
Copy the code

Conversion of reference types

The comparison between basic types is relatively simple. The comparison between a reference type and a primitive type is a bit more complicated.

PreferredType Indicates the PreferredType conversion policy
  • If the PreferredType is marked as Number, the following process is used to convert the input value.
  1. If the entered value is already an original value, it is returned directly
  2. Otherwise, if the input value is an object, the valueOf() method of that object is called, and if the valueOf() method returns a raw value, the original value is returned.
  3. Otherwise, the object’s toString() method is called, which returns a raw value if it returns one.
  4. Otherwise, TypeError is thrown.
  • If the PreferredType is marked as String, the following process is used to convert the input value.
  1. If the entered value is already an original value, it is returned directly
  2. Otherwise, the object’s toString() method is called, which returns a raw value if it returns one.
  3. Otherwise, if the input value is an object, the valueOf() method of that object is called, and if the valueOf() method returns a raw value, the original value is returned.
  4. Otherwise, TypeError is thrown.

Note that the PreferredType value is automatically set according to this rule:

  1. The object is of type Date, so the PreferredType is set to String
  2. Otherwise, the PreferredType is set to Number

case

console.log([] + []);  // "(empty string)
Copy the code

Call valueOf() first, the result is still [], not the original value, so continue toString(), the result is “” (empty string) the original value, return” “. The second [] procedure is the same, returning “”. Both sides of the plus sign are strings, so concatenate the String and the result is “”.

console.log([] + {});  //[object object] (string)
Copy the code

ToPrimitive, still using Number as the conversion criteria. [] is the result of. {} first call valueOf(), the result is {}, not the original value, so continue to call toString(), the result is “[object object]”, is the original value, return “[object object]”. Both sides of the plus sign result in String type, so String concatenation, the result is “[object object]”.

console.log({} + []);
// In global it is [object object]
// On the console it is 0
Copy the code
console.log({} + {});  //[object object][object object] (String)
Copy the code

In the Canary version of Chrome and Node, the results were as expected. The result is “Object object”. In the normal version of Chrome the result is NaN. Why is that? The reason is that node wraps () around statements that start with “{” and end with”} “so that they become ({} + {}). The normal version of Chrome still resolves to {}; +{}, the result becomes NaN