I'm using moment.js in a current project and I see that the comparison operators <,>,>=,<= work correctly. However == does not.
It surprises me that these work and that you don't need to use the .isBefore() and .isAfter() functions.
Can anyone give me a brief description of why these work? Would it be possible to make == work as well?
Thanks.
This is due to how comparison and equality operators in JavaScript work (emphasis mine):
For relational abstract comparisons (e.g., <=), the operands are first converted to primitives, then to the same type, before comparison.
[...]
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
So when two moment objects are compared with inequalities, they are first converted to numbers. For Moment.js objects, this is milliseconds since the unix epoch of midnight UTC, Jan 1st 1970.
In your favorite browser's console window/node REPL:
> +moment()
<- 1412332710977
For the ==
equality check, the runtime does a reference comparison between the two objects, which returns false
for two different moment instances, even if they both are for the same date/time.
A lack of default .equals()
or operator==()
overloading in JavaScript makes this behaviour rather counter-intuitive, especially if you're coming from other languages.
Also note that Moment's isBefore
/isAfter
functions are really slow, as they clone both moment objects internally before doing the comparison (this is because there is an optional argument to isBefore
/isAfter
to specify which time component to compare on (e.g. 'hour'
) and it clones regardless of whether this argument is present or not).
Moment suffers here from having mutable objects, which is why it is doing a defensive clone()
in the first place, and then further from not having optimised the common path where this is actually unnecessary.
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