Why can I do math with Date objects? [duplicate]

  • A+
Category:Languages

This question already has an answer here:

When I subtract two Date-objects like this:

const startTime = new Date(); await someAsyncStuff(); const endTime = new Date();  const elapsedTime = endTime - startTime; console.log(`The async stuff took ${elapsedTime} ms`); 

Why does the Date objects end up being cast to milliseconds, which are then subtracted? I understand that they do, but I can't figure out what the actual sequence of events is that lead to this.

 


It's how javascript does automatic type conversion - just like arithmetic operations (that you are performing here). You were lucky that you subtracted, if you've added them you'd end up with a string holding two date strings in a row because of how toPrimitive (that gets called implicitly) works for Dates. Consider the following

// automatic casting console.log("1" - "1"); // 0 // but console.log("1" + "1"); // 11  // now with dates // automatic casting console.log(new Date() - new Date()); 0 console.log(new Date() + new Date()); // Mon Jun 11 2018 10:10:36 GMT+0200 (Mitteleuropäische Sommerzeit)Mon Jun 11 2018 10:10:36 GMT+0200 (Mitteleuropäische Sommerzeit)

The specification on the additional operator has the following hint that explains this further

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.

JavaScript converts your value to a primitive when using arithmetic opererators, the method that gets called here is

Date.prototype [ @@toPrimitive ] ( hint ) 

Date.prototype [ @@toPrimitive ] ( hint ) 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".

That said. The reason why your code works how it works is the later auto conversion performed by the subtraction, which gives hint to toPrimitive to return a number.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: