JavaScript addition rules

In JavaScript, the rules for addition are simple, with only two cases:

  • Add numbers to numbers
  • String and string addition

All other types of values are automatically converted to values of these two types

In JavaScript, there are two types of values:

  • The original values are:undefined,nullBoolean, number, string, symbol
  • Object values: All the other values are of object types, including arrays and functions.

Type conversion

The addition operator triggers three types of conversion: converting a value to a raw value, converting it to a number, and converting it to a string, which corresponds to the three abstraction operations inside the JavaScript engine :ToPrimitive(), ToNumber(), and ToString().

The value is converted to the original value by ToPrimitive()

ToPrimitive(input, PreferredType?)
Copy the code

The optional parameter PreferredType, which can be either Number or String, represents a conversion preference. The conversion result does not have to be the type indicated by the parameter, but the conversion result must be a raw value. If PreferredType is marked as Number, the following operation is done to convert the input value (§9.1):

  1. If the input value is already a primitive value, it is returned.
  2. Otherwise, if the input value is an object. The object’sThe valueOf () method. IfThe valueOf () methodIf the return value of is a raw value, the original value is returned.
  3. Otherwise, the object’sThe toString () method. IftoString()Method whose return value is a raw value, returns the original value.
  4. Otherwise, throwTypeError abnormal.

If the PreferredType is marked as String, the order of the second and third steps of the conversion operation is reversed. If there is no PreferredType parameter, the value of the PreferredType is automatically set to String for dates and Number for other values.

Convert the value to a number with ToNumber()

parameter The results of
undefined NaN
null + 0
Boolean value True is converted to 1.False converts to +0
digital Without conversion
string Parsing a string to a number. For example,”324" is converted to 324

If the input value is an object, ToPrimitive(obj, Number) is first called to convert the object to its original value, and ToNumber() is then called to convert the original value to a Number.

The value is converted to a string by ToString()

parameter The results of
undefined "undefined"
null "null"
Boolean value "True" or "false"
digital Numbers as strings, for example."1.765"
string Without conversion

If the input value is an object, ToPrimitive(obj, String) is called first to convert the object to its original value, and ToString() to convert the original value to a String.

demo

var obj = {
    valueOf: function () {
        console.log("valueOf");
        return {}; // No original value is returned
    },
    toString: function () {
        console.log("toString");
        return {}; // No original value is returned}}Copy the code

When Number is called as a function (rather than as a constructor), the ToNumber() operation is called inside the engine:

Number(obj)

// output
valueOf
toString
Uncaught TypeError: Cannot convert object to primitive value

String(obj)
// output
toString
valueOf
Uncaught TypeError: Cannot convert object to primitive value
Copy the code

add

    value1 + value2
Copy the code

When evaluating this expression, the steps are as follows:

  1. Convert the two operands to their original values (here is the mathematical notation, not JavaScript code):

        prim1 := ToPrimitive(value1)
        prim2 := ToPrimitive(value2)
    Copy the code

    PreferredType is omitted, so values of Date type take String and values of other types take Number.

  2. If either prim1 or prim2 is a string, it converts the other to a string and returns the result of the concatenation of the two strings.

  3. Otherwise, convert both prim1 and prim2 to numeric types and return their sum.

[] + []

Output: “‘

[] is converted to a raw value, first try the valueOf() method, which returns the array itself (this):

> var arr = [];
> arr.valueOf() === arr
true
Copy the code

The result is not a raw value, so call toString(), which returns an empty string (a raw value). Therefore, the result of [] + [] is actually a concatenation of two empty strings.

> [] + {}
'[object Object]'
Copy the code

{} + {}

Output: NaN

  1. The JavaScript engine interprets the first {} as an empty block of code and ignores it
  2. The plus sign here is not the binary operator for addition, but rather a unary operator that converts the operand following it to a Number, exactly as the Number() function does. Such as:
Number + {} ({}) Number ({}. The toString ()) / / because {}. The valueOf () is not the original value Number (" [object object] ") NaNCopy the code
> {} + []
0
Copy the code
  1. {} to ignore
  2. +[] = Number([]) = Number([].toString()) = Number(“”) = 0

Interestingly, node.js’s REPL parses similar input differently than Firefox and Chrome, which use the V8 engine like Node.js. The following input is parsed into an expression that is more like what we would expect:

> {} + {}
'[object Object][object Object]'
> {} + []
'[object Object]'
Copy the code

conclusion

ValueOf () === object

Array object.toString () === Array object.join ()

Object. ToString () === "[object object]"

Javacript + work:

  1. Number + number
  2. String + String

The object value is converted to the original value before it is evaluated

See article: Type conversion