Reputation: 48090
What Javascript language rule leads to the following conversion weirdness?
new Date() - 2 => number
new Date() * 2 => number
new Date() / 2 => number
but
new Date() + 2 => string
I had thought that the + operator would use the valueOf()
method of the Date
object to convert it to a number. Like in the following example:
{valueOf: function() {return 1;}} + 2 => number
What is different in the case of a Date
?
Upvotes: 2
Views: 229
Reputation: 48090
After studying the Javascript spec, there is indeed a special case for Date objects in the context of the addition operator:
http://ecma-international.org/ecma-262/5.1/#sec-11.6.1
Conversion of a Date object is handled differently than for other objects:
No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given.
I think I understand the motivation, but as a language rule, this feels quite ugly.
Upvotes: 0
Reputation: 123397
when you try to do
new Date() + 2
you're doing a string concatenation (so new Date()
is returning a string representation of the Date
object equivalent to (new Date()).toString()
),
In the in other cases you're using an arithmetic operator (and in this case new Date()
returns the milliseconds from "Epoch")
To have a "consistent" behaviour make a type coercion just using +(new Date())
so that
+(new Date()) - 2 => number
+(new Date()) * 2 => number
+(new Date()) / 2 => number
+(new Date()) + 2 => number
Upvotes: 3
Reputation: 76433
It's not inconsistent: Just try d = new Date(); console.log(d);
the toString
method, that is implicitly invoked in the above code returns a string by default. Since JS is loosely typed, and +
is an overloaded operator (concatenates strings, and does arithmetic), both the date object and the int (2) are coerced:
I guess the logic behind this is something like: if neither operand is directly compatible, both are coerced to a third type: sort of "Meeting each other half-way". Dates are converted to strings by default, and a number can do that, too, so JS assumes that is what you want (it being the most logic interpretation).
The other examples use different operands, that leave no room for interpretation, hence the date-object's numeric value is used
It's an easy fix, though:
+(new Date()) + 2;//+ coerces new Date() to int
Here's some more info
Upvotes: 1