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
,null
Boolean, 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):
- If the input value is already a primitive value, it is returned.
- Otherwise, if the input value is an object. The object’s
The valueOf () method
. IfThe valueOf () method
If the return value of is a raw value, the original value is returned. - Otherwise, the object’s
The toString () method
. IftoString()
Method whose return value is a raw value, returns the original value. - Otherwise, throw
TypeError 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:
-
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.
-
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.
-
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
- The JavaScript engine interprets the first {} as an empty block of code and ignores it
- 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
- {} to ignore
- +[] = 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:
- Number + number
- String + String
The object value is converted to the original value before it is evaluated
See article: Type conversion