Как проверить, является ли объект датой? - PullRequest
480 голосов
/ 13 марта 2009

У меня раздражающая ошибка на веб-странице:

date.GetMonth () не является функцией

Итак, я полагаю, что я делаю что-то не так. Переменная date не является объектом типа Date. Как я могу проверить тип данных в Javascript? Я пытался добавить if (date), но он не работает.

function getFormatedDate(date) {
    if (date) {
       var month = date.GetMonth();
    }
}

Итак, если я хочу написать защитный код и предотвратить форматирование даты (не одной), как мне это сделать?

Спасибо!

ОБНОВЛЕНИЕ: Я не хочу проверять формат даты, но хочу убедиться, что параметр, переданный методу getFormatedDate(), имеет тип Date.

Ответы [ 16 ]

934 голосов
/ 13 марта 2009

Как альтернатива печати по утке через

typeof date.getMonth === 'function'

вы можете использовать оператор instanceof, т. Е. Он вернет истину и для недопустимых дат, например, new Date('random_string') также является экземпляром Date

date instanceof Date

Это не удастся, если объекты пройдут через границы кадра.

Обходной путь для этого - проверить класс объекта с помощью

Object.prototype.toString.call(date) === '[object Date]'
110 голосов
/ 24 апреля 2013

Вы можете использовать следующий код:

(myvar instanceof Date) // returns true or false
43 голосов
/ 26 мая 2017

Чтобы проверить, является ли значение допустимым типом стандартного объекта JS-date, вы можете использовать этот предикат:

function isValidDate(date) {
  return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
  1. date проверяет, не является ли параметр ложным значением (undefined, null, 0, "" и т. Д.)
  2. Object.prototype.toString.call(date) возвращает собственное строковое представление данного типа объекта - в нашем случае "[object Date]". Поскольку date.toString() переопределяет его родительский метод , нам необходимо .call или .apply метод из Object.prototype напрямую, который ..
    • Обходит определенный пользователем тип объекта с тем же именем конструктора (например, «Дата»)
    • Работает в разных контекстах JS (например, iframes) в в отличие от instanceof или Date.prototype.isPrototypeOf.
  3. !isNaN(date) наконец проверяет, не было ли значение Invalid Date.
37 голосов
/ 13 марта 2009

Функция getMonth(), а не GetMonth().

В любом случае, вы можете проверить, имеет ли объект свойство getMonth, выполнив это. Это не обязательно означает, что объект является Date, просто любой объект, который имеет свойство getMonth.

if (date.getMonth) {
    var month = date.getMonth();
}
19 голосов
/ 13 марта 2009

Как указано выше, вероятно, проще всего проверить, существует ли функция перед ее использованием. Если вас действительно волнует, что это Date, а не просто объект с функцией getMonth(), попробуйте следующее:

function isValidDate(value) {
    var dateWrapper = new Date(value);
    return !isNaN(dateWrapper.getDate());
}

Это создаст либо клон значения, если оно Date, либо создаст недопустимую дату. Затем вы можете проверить, является ли значение новой даты недействительным или нет.

17 голосов
/ 13 марта 2009

Для всех типов я создал функцию-прототип Object. Это может быть полезно для вас

Object.prototype.typof = function(chkType){
      var inp        = String(this.constructor),
          customObj  = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9),
          regularObj = Object.prototype.toString.apply(this),
          thisType   = regularObj.toLowerCase()
                        .match(new RegExp(customObj.toLowerCase()))
                       ? regularObj : '[object '+customObj+']';
     return chkType
            ? thisType.toLowerCase().match(chkType.toLowerCase()) 
               ? true : false
            : thisType;
}

Теперь вы можете проверить любой тип следующим образом:

var myDate     = new Date().toString(),
    myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String

[ Редактировать март 2013 ], основываясь на прогрессирующем понимании, это лучший метод:

Object.prototype.is = function() {
        var test = arguments.length ? [].slice.call(arguments) : null
           ,self = this.constructor;
        return test ? !!(test.filter(function(a){return a === self}).length)
               : (this.constructor.name ||
                  (String(self).match ( /^function\s*([^\s(]+)/im)
                    || [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Some = function(){ /* ... */}
   ,Other = function(){ /* ... */}
   ,some = new Some;
2..is(String,Function,RegExp);        //=> false
2..is(String,Function,Number,RegExp); //=> true
'hello'.is(String);                   //=> true
'hello'.is();                         //-> String
/[a-z]/i.is();                        //-> RegExp
some.is();                            //=> 'ANONYMOUS_CONSTRUCTOR'
some.is(Other);                       //=> false
some.is(Some);                        //=> true
// note: you can't use this for NaN (NaN === Number)
(+'ab2').is(Number);                 //=> true
8 голосов
/ 05 мая 2016

UnderscoreJS и Lodash имеют функцию с именем .isDate(), которая, как представляется, именно то, что вам нужно. Стоит посмотреть на их соответствующие реализации: Lodash isDate , UnderscoreJs

6 голосов
/ 15 сентября 2016

Лучший способ, который я нашел, это:

!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001"))  // true
!isNaN(Date.parse("blabla"))  // false
3 голосов
/ 13 марта 2009

Вы можете проверить, существует ли функция, специфичная для объекта Date:

function getFormatedDate(date) {
    if (date.getMonth) {
        var month = date.getMonth();
    }
}
2 голосов
/ 22 августа 2016

Также вы можете использовать краткую форму

function getClass(obj) {
  return {}.toString.call(obj).slice(8, -1);
}
alert( getClass(new Date) ); //Date

или как-то так:

(toString.call(date)) == 'Date'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...