Reputation: 3342
From my understanding if an object has valueOf
function it will be used when object needs to be converted into a primitive. If an object has toString
function it will be used when object needs to be converted into a string. So when you use +
it should first use valueOf
if present and then toString
.
That's what it seems to do from :
var obj1 = {
valueOf: () => 0
};
var obj2 = {
toString: () => 'a'
};
var obj3 = {
valueOf: () => 0,
toString: () => 'a'
};
obj1 + obj1; // -> 0
obj2 + obj2; // -> 'aa'
obj3 + obj3; // -> 0
Now Date is implementing both valueOf
and toString
like obj3
but when you do date + date
you get a string !
Using any other arithmetic operators will treat date as a number do the operation and return a valid number.
Here is some code to demonstrate my confusion :
var date = new Date(2017,1,1);
date - date; // -> 0
date * date: // -> 2.20790950849296e+24
date / date; // -> 1
date % date; // -> 0
date + date; // -> "Wed Feb 01 2017 00:00:00 GMT+0100 (CET)Wed Feb 01 2017 00:00:00 GMT+0100 (CET)"
Upvotes: 1
Views: 212
Reputation: 1017
An Object can be converted to a primitive value with the help of the Symbol.toPrimitive property (used as a function value).
The function is called with a string argument hint, which specifies the preferred type of the result primitive value. The hint argument can be one of "number", "string", and "default".
Syntax for Date objects : Date()[Symbol.toPrimitive](hint);
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.
If hint is "number", @@toPrimitive first tries to call valueOf, and if that fails, it calls toString.
var date = new Date(2017,1,1);
console.log('hint is "number":',+date + +date); // using unary plus operator
console.log('hint is "default":',date + date); // no hint (falls to hint == 'string')
console.log('hint is "string":',`${date + date}`); // using template literals
The +
operator is the most confusing among all arithmetic operators. without a hint to convert the Date instance to a number, it acts as a string concatenator
Upvotes: 0
Reputation: 5193
That is because Date
has an exotic @@toPrimitive
which prefers string over number. See #sec-date.prototype-@@toprimitive
Date objects, are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string", All other built-in ECMAScript objects treat "default" as being equivalent to "number".
Upvotes: 1
Reputation: 6088
The +
operator will act as a concatenator in JS if the first operand is a string. Since date
yields a string, it will act as a concatenator in this case.
Upvotes: 0