I'm trying to understand this behaviour:
var d = new Date();
console.log(+d); // 1458049171381
console.log(1 + d); // '1Tue Mar 15 2016 09:39:31 GMT-0400 (EDT)'
In contrast to:
var obj = {
valueOf: function () {
return 123;
}
};
console.log(+obj); // 123
console.log(1 + obj); // 124
Why does the Date
addition result in a string
when Date.prototype.valueOf
returns a number
?
Here is naive translation of the Addition Operator's spec to JavaScript
function ToPrimitive(x) {
return x.valueOf();
}
function IsString(x) {
return typeof x === 'string';
}
function ToString(x) {
return x.toString();
}
function ToNumber(x) {
try {
return parseFloat(x);
} catch (e) {
return NaN;
}
}
function AdditionOperator(lval, rval) {
let lprim = ToPrimitive(lval);
let rprim = ToPrimitive(rval);
if (IsString(lprim) || IsString(rprim)) {
return ToString(lprim) + ToString(rprim);
} else {
return ToNumber(lprim) + ToNumber(rprim);
}
}
However, if I invoke this with a Date
object, it returns a numeric value:
AdditionOperator(new Date(), 1) // 1458049347088
Can someone shed some light on this?
Walk-through:
Before the addition takes place, both the left and right values
of the binary operation are converted to primitives (string
or number
).
Depending on the context of the value, it might be provided a 'hint' which suggests which primitive type it should become.
If no hint is provided, it will default to its preferred type. All Object
s have a preferred type of number
except for Date
, which prefers string
(and confuses everyone).
As per the spec
All standard 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. Exotic objects may handle the absence of a hint in some other manner.
And in case of Date they make an exception
Of the objects defined in this specification only Date objects (see 20.3.4.45) and Symbol objects (see 19.4.3.4) over-ride the default ToPrimitive behaviour. Date objects treat no hint as if the hint were String.
Also, check this
This function is called by ECMAScript language operators to convert a Date object to a primitive value. The allowed values for hint are "default", "number", and "string". 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".
So, Date is used as String only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With