Reputation: 35
d = new Date();
d; // it is a string: Fri Apr 23 2021 10:30:34 GMT+0800(..)
d - 0; // it is a number: 1619145034656
d + 0; // it is a string: Fri Apr 23 2021 10:30:34 GMT+0800(..)0
d * 2; // it is a number: 3238290069312
d / 2; // it is a number: 809572517328
d.valueOf(); // it is a number: 1619145034656
d.toString(); // it is a string "Fri Apr 23 2021 10:30:34 GMT+0800 (...)"
I could accept all arithmetic but add(+), know '+' could be used for concating two string, but d.valueOf() is a number.
How Date objects know when use a string as it's value and when use number as it's value?
Upvotes: 1
Views: 93
Reputation: 371049
When operators like these are used, the specification runs a particular sequence of operations. If the operator used is +
:
2. If opText is +, then
a. Let lprim be ? ToPrimitive(lval).
b. Let rprim be ? ToPrimitive(rval).
And calling ToPrimitive
on a Date results in the string representation of the Date being returned.
In contrast, all of the other operators like -
*
/
result in the other branch of the specification running:
3. NOTE: At this point, it must be a numeric operation.
4. Let lnum be ? ToNumeric(lval).
5. Let rnum be ? ToNumeric(rval).
...
9. Return ? operation(lnum, rnum).
The main difference is that +
can be used to either add or concatenate. When either side is an object, it will cast the objects to strings, then concatenate. When any other operator is used, it will case the objects to numbers, then perform the appropriate arithmetic operation.
When ToPrimitive
is called on a Date, the Date's @@toPrimitive
method runs with no hint, which does:
If hint is string or default, @@toPrimitive tries to call the toString method. If the toString property does not exist, it tries to call the valueOf method and if the valueOf does not exist either, @@toPrimitive throws a TypeError.
As you can see, when called with no hint, the Date is cast to a string.
Upvotes: 1