920 votes

Comment vérifier si un objet est une date ?

J'ai un bug ennuyeux sur une page web :

date.GetMonth() n'est pas une fonction

Donc, je suppose que je fais quelque chose de mal. La variable date n'est pas un objet de type Date . Comment vérifier un type de données en Javascript ? J'ai essayé d'ajouter un if (date) mais ça ne marche pas.

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

Donc, si je veux écrire un code défensif et empêcher la date (qui n'en est pas une) d'être formatée, comment dois-je faire ?

Merci !

UPDATE : Je ne veux pas vérifier le format de la date, mais je veux m'assurer que le paramètre passé à la méthode getFormatedDate() est de type Date .

0 votes

Dans le cas où il faudrait également valider si le date n'est pas un Invalid Date : stackoverflow.com/a/44198641/5846045

1565voto

Christoph Points 64389

Comme alternative à la saisie en canard via

typeof date.getMonth === 'function'

vous pouvez utiliser le instanceof Mais il retournera vrai pour les dates invalides aussi, par exemple. new Date('random_string') est également une instance de Date

date instanceof Date

Cela échouera si les objets sont transmis au-delà des limites de la trame.

Une solution de contournement consiste à vérifier la classe de l'objet par l'intermédiaire de

Object.prototype.toString.call(date) === '[object Date]'

38 votes

Par curiosité, connaissez-vous la raison de cet échec lors du passage à travers les limites de la trame ?

109 votes

@Simon : Les globaux JS sont locaux à l'objet global courant (aka window ou self ) ; les différents cadres ont leurs propres objets globaux, et leurs propriétés (c'est-à-dire les globaux) font référence à des objets distincts : Date dans le cadre 1 est un objet fonctionnel différent de Date dans le cadre 2 ; il en va de même pour Date.prototype qui est à l'origine de la instanceof l'échec : Date.prototype du cadre 1 ne fait pas partie de la chaîne du prototype de Date instances du cadre 2

2 votes

Pour l'élaboration du instanceof qui échouent au-delà des limites du cadre, voir JavaScript Garden : "... instanceof ne fonctionne pas sur les objets qui proviennent de différents contextes JavaScript (par exemple, différents documents dans un navigateur web), puisque leurs constructeurs ne seront pas exactement le même objet."

218voto

user2286502 Points 189

Vous pouvez utiliser le code suivant :

(myvar instanceof Date) // returns true or false

10 votes

Pourquoi cette réponse n'est-elle pas la réponse acceptée ou la plus votée ? Le simple fait de vérifier si la date possède une propriété .getMonth pourrait déclencher un faux positif.

33 votes

Instanceof peut déclencher des faux négatifs, voir le commentaire de Christoph à sa propre réponse.

3 votes

@doremi Voici une démo de instanceof déclenchant un faux négatif : jsbin.com/vufufoq/edit?html,js,console

40voto

Chetan Sastry Points 14742

La fonction est getMonth() pas GetMonth() .

Quoi qu'il en soit, vous pouvez vérifier si l'objet a une propriété getMonth en faisant ceci. Cela ne signifie pas nécessairement que l'objet est une date, mais simplement que tout objet possède une propriété getMonth.

if (date.getMonth) {
    var month = date.getMonth();
}

4 votes

Vérifiez si elle est rachetable : if (date.getMonth && typeof date.getMonth === "function") {...}

25voto

bdukes Points 54833

Comme indiqué ci-dessus, il est probablement plus simple de vérifier si la fonction existe avant de l'utiliser. Si vous tenez vraiment à ce qu'il s'agisse d'une Date et pas seulement un objet avec un getMonth() essayez ceci :

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

Cela créera soit un clone de la valeur si c'est un Date ou créer une date non valide. Vous pouvez alors vérifier si la valeur de la nouvelle date est invalide ou non.

1 votes

Cela a fonctionné pour moi, merci. Cependant, si vous passez un chiffre unique tel que 0 ou 1, il le traite comme une date valide... une idée ?

0 votes

C'est exact, @RicardoSanchez. Vous voulez probablement utiliser la réponse acceptée ( Object.prototype.toString.call(value) === '[object Date]' ) s'il est possible que vous obteniez des chiffres. La méthode utilisée dans cette réponse vous indique réellement si les value est convertible en un Date .

18voto

KooiInc Points 38845

Pour tous les types, j'ai préparé une fonction de prototype d'objet. Elle peut vous être utile

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;
}

Vous pouvez maintenant vérifier tout comme ceci :

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

[ Edition mars 2013 ] sur la base d'un aperçu progressif, c'est une meilleure méthode :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X