-2

I have read the this question on SO, but here I am asking why the below semantics are allowed

Take the following Javascript example:

window - window = NaN

window - document = NaN

but

new Date() - new Date() = 0
new Date / new Date() = 1
new Date * new Date() = 2.2659874948410516e+24

Why does this work ? These code snippets were executed in Chrome console and I have a couple of questions about what is happening here:

Firstly, why is it even allowed in Javascript to do arithmetic operations on Date ? Is it a special type of object that is magically allowed these abilities ? Is Date even treated internally as an object ? Why then even force us to create a Date() like a normal object ?

Secondly, what does it even mean to subtract, or multiply two dates ?

Thirdly, is Date the only exception or are there other object that have these "superpowers"(other than string), also can they be replicated in user-defined code ?

ng.newbie
  • 2,807
  • 3
  • 23
  • 57
  • Because js isn't a strong typed language., check this out; https://stackoverflow.com/questions/24182317/multiplication-with-date-object-javascript – clearshot66 Sep 13 '17 at 16:33
  • 3
    Because JS date is essentially the count of miliseconds from 1st January 1970? – Nisarg Shah Sep 13 '17 at 16:33

2 Answers2

3

You can implement it yourself ( be superman!). Using the +*-/ on an object tries to convert that object to a primitive through either calling one of these:

obj.toString() //if string is required
obj.valueOf() // if number is required

So to make that behaviour, just define that methods:

class one {
 valueOf(){ return 1; }
}

alert( new one + new one)//2
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • So how does Javascript know when String is toString() and when valueOf() is required ? Like for Strings '+' means concatenation, but the example given above means valueOf(), If both are implemented how does JS know what to call ? – ng.newbie Sep 13 '17 at 16:42
  • @mg.newbie -/* => valueOf, + => https://stackoverflow.com/questions/2485632/valueof-vs-tostring-in-javascript – Jonas Wilms Sep 13 '17 at 16:46
1

JS supports a rudimentary form of operator overloading so that arithmetic operators, when applied to an object, invoke its special valueOf method to obtain a numeric value:

a = {};
a.valueOf = () => 1;

b = {};
b.valueOf = () => 2;

console.log(a + b)

Date objects define valueOf so that it returns milliseconds from the epoch.

Note that valueOf is only invoked in the "numeric" context, which is the case for - * /, but not for +. If you're going to add something to a Date, convert to the Number first:

today = new Date
tomorrow = new Date(Number(today) + 24 * 3600 * 1000)
console.log(tomorrow)
georg
  • 211,518
  • 52
  • 313
  • 390