JavaScript automatically performs implicit type conversions before performing an operation or comparison. Let’s take a closer look at what happens to the + – * / == operator.

Type conversion

The ECMAScript runtime system does automatic type conversions when needed. To clarify the semantics of some structures, it is useful to define a set of transformation operators. These operators are not part of the language; They are defined here to assist in the specification of language semantics.

  • ToPrimitive
  • ToNumber
  • ToString
  • ToBoolean
  • ToInteger
  • ToInt32 :(32-bit signed integer)
  • ToUint32 :(32-bit unsigned integer)
  • ToUint16 :(16-bit unsigned integer)
  • ToObject

The first three are detailed below

ToPrimitive

Convert to original type.

ToPrimitive(input, PreferredType)
Copy the code
Input type The results of
Undefined The result is equal to the input parameter (no conversion).
Null The result is equal to the input parameter (no conversion).
Boolean The result is equal to the input parameter (no conversion).
Number The result is equal to the input parameter (no conversion).
String The result is equal to the input parameter (no conversion).
Object Returns the default value for this object.

The DefaultValue of the object is obtained by calling the internal method [[DefaultValue]] of the object, passing the PreferredType as the hint parameter

Object internal method [[DefaultValue]] (hint)

When a String hint calls O’s [[DefaultValue]] inner method, do the following:

  1. str = O.toString();
  2. If STR is the original value, return STR;
  3. val = O.valueOf();
  4. Return val if val is the original value;
  5. Raises a TypeError exception.

When the Number hint calls O’s [[DefaultValue]] inner method, do the following:

  1. val = O.valueOf();
  2. Return val if val is the original value;
  3. str = O.toString();
  4. If STR is the original value, return STR;
  5. Raises a TypeError exception.

When no hint calls O’s [[DefaultValue]] inner method, hint=String if O is Date, and hit=Number otherwise.

Example:

ToPrimitive({})ObjectIf [[DefaultValue]] does not invoke hint, hint isNumberval = O.valueOf(); STR = o.tostring (); STR is'[object Object]', is the original value and returns'[object Object]'Results:'[object Object]'
Copy the code

ToNumber

Convert to a Number type.

Input Type Result
Undefined NaN
Null + 0
Boolean true: 1, false: +0
Number The result is equal to the input parameter (no conversion).
String Converts strings to numbers.
Object Apply the following steps:

1. Call ToPrimitive(input argument, hint Number).

2. Call ToNumber(Result(1)).

3. Return Result(2).

ToString

Convert to a String.

Input type The results of
Undefined “undefined”
Null “null”
Boolean If the argument is true, the result is “true”.

If the argument is false, the result is “false”.
Number Converts numbers to strings.
String The result is equal to the input parameter (no conversion).
Object Apply the following steps:

1. Call ToPrimitive(input argument, hint String).

2. Call ToString(Result(1)).

3. Return Result(2).

Example:

var obj = {
    valueOf: function () {
        return 1;
    },
    toString: function () {
        return 2; }}Number(obj) parse: obj typeObject, the call ToPrimitive (obj,Number) withNumberHint calls obj's [[DefaultValue]] inner method and calls obj's valueOf method1Return ToNumber (1Results:1

String(obj) parse: obj typeObject, the call ToPrimitive (obj,String) withStringHint calls obj's [[DefaultValue]] inner method to call obj's toString method2Returns the ToString (2Results:'2'
Copy the code

A practical use of type conversions

The plus operator +

Lval + rval

  1. Make lprim ToPrimitive (lval).
  2. Make rprim ToPrimitive (rval).
  3. If Type(lprim) is String or Type(rprim) is String, then: returns the concatenated String of ToString(lprim) and ToString(rprim).
  4. Returns the result of applying addition to ToNumber(lprim) and ToNumber(rprim).

Example:

([] + {})1. lprim = ToPrimitive([]); / /"
    2. rprim = ToPrimitive({}); // '[object Object]'
    3.Lprim and rprim are both strings and return ToString(' ') + ToString('[object Object]') // '[object Object]'Results:'[object Object]'

(undefined+ {});1. lprim = ToPrimitive([]); // undefined;
    2. rprim = ToPrimitive({}); // '[object Object]';
    3.Type (rprim)StringTo return to ToString (undefined) + ToString('[object Object]') // 'undefined[object Object]'Results:'undefined[object Object]'

(undefined + 1Resolution:1. lprim = ToPrimitive([]); // undefined;
    2. rprim = ToPrimitive(1); / / 1.
    3.Type(lprim) Type(rprim) neitherString;
    4.Return ToNumber (undefined) + ToNumber(1) // NaNResults:NaN
Copy the code

Other operators – * /

The – * / operators for lval and rval flow as follows:

  1. Make lnum is ToNumber (lval).
  2. Make rnum ToNumber (rval).
  3. Returns the results of ToNumber(lprim) and ToNumber(rprim) operations.

Non-strict equality comparison

The compared value B
Undefined Null Number String Boolean Object
The value being compared is A Undefined true true false false false IsFalsy(B)
Null true true false false false IsFalsy(B)
Number false false A === B A === ToNumber(B) A=== ToNumber(B) A== ToPrimitive(B)
String false false ToNumber(A) === B A === B ToNumber(A) === ToNumber(B) ToPrimitive(B) == A
Boolean false false ToNumber(A) === B ToNumber(A) === ToNumber(B) A === B ToNumber(A) == ToPrimitive(B)
Object false false ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToNumber(B)

A === B

Example:

[] == {}
-> this == this
-> false

[] == 0
-> ToPrimitive([]) == 0
-> ' ' == 0
-> ToNumber(' '== 0 -> 0 == 0 ->true

[0] == 0
-> ToPrimitive([0]) == 0
-> '0' == 0
-> ToNumber('0'== 0 -> 0 == 0 ->true[11] = = 11 - >true

['0'] = =false
-> ToPrimitive(['0']) == ToNumber(false) - >'0' == 0
-> 0 == 0
-> true(= = {}'[object Object]')
-> ToPrimitive({}) == '[object Object]'
-> '[object Object]'= ='[object Object]'
-> true
Copy the code

reference

  • ECMAScript5.1 Chinese version
  • Equality judgment in JavaScript