Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Date addition result in a string?

Tags:

javascript

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?

like image 691
Ilia Choly Avatar asked Mar 15 '16 13:03

Ilia Choly


1 Answers

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 Objects 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.

like image 183
gurvinder372 Avatar answered Oct 22 '22 10:10

gurvinder372