39

I'm attempting to understand types in the JavaScript world. My page is using moment.js. I have a function that sometimes returns a moment() and other times, returns a string (it's legacy code gone wild).

My code kind of looks like this:

var now = getDate();
if (now instanceof moment) {
  console.log('we have a moment.');
} else {
  console.log('we have a string.');
}


function getDate() {
  var result = null;
  // Sometimes result will be a moment(), other times, result will be a string.
  result = moment();
  return result;
}

When I execute the code above, I never get we have a moment.. Even if I manually make set result = moment();. Why is that? Am I misunderstanding instanceof or moment?

AST
  • 211
  • 6
  • 18
Some User
  • 5,257
  • 13
  • 51
  • 93

2 Answers2

55

Moment version 2.13.0

There is a static method .isMoment:

enter image description here

FreeLightman
  • 2,224
  • 2
  • 27
  • 42
41

First of all, instanceof isn't perfectly reliable.

Second of all, moment() returns instance of Moment class that isn't exposed to user. Following code prove this:

moment().__proto__.constructor // function Moment()
moment().constructor === moment; // false

Third of all, moment provide function moment.isMoment that will solve your problem.

And last, but not least - your code should use consistent return types - always return moment instances or always return strings. It will reduce your pain in future.

You can ensure that you always have moment instance by calling moment function - moment(string) equals in value moment(moment(string)), so you can just always convert your argument to moment instance.

Ginden
  • 5,149
  • 34
  • 68
  • 1
    shouldn't you be checking `moment().constructor === moment`? – G_hi3 Aug 10 '15 at 13:44
  • 2
    I think this is out of date. `isMoment` is undefined. Also, the difference between `isMoment()` (or `isValid()`, which I think is the current equivalent) and typeof/instanceof can be fairly significant in the right circumstances. – Trevor Aug 20 '15 at 22:22
  • 2
    You should call moment.isMoment(moment()) and not moment().isMoment(). – todinov Jul 18 '16 at 11:19
  • 3
    [The docs](https://momentjs.com/docs/) says: "From version 2.11.0, you can also test for a moment object by instanceof operator: moment() instanceof moment // true" – x-yuri Jun 05 '18 at 19:39
  • I was attesting to my friend that js would be capable of giving erroneous values for `instanceof` and there it is. I code in JS but sometimes those little things make it feel a little less reliable. – tatsu Sep 24 '18 at 15:00