J'ai un bug gênant 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 puis-je vérifier un type de données en Javascript? J'ai essayé d'ajouter une if (date)
, mais cela ne fonctionne pas.
function getFormatedDate(date) {
if (date) {
var month = date.GetMonth();
}
}
Donc, si je veux écrire du code défensif et empêcher la date (qui n'en est pas une) d'être formatée, comment puis-je le faire?
Merci!
PDATE: Je ne veux pas vérifier le format de la date, mais je veux être sûr que le paramètre transmis à la méthode getFormatedDate()
est de type Date
.
Comme alternative à la frappe de canard via
typeof date.getMonth === 'function'
vous pouvez utiliser l’opérateur instanceof
, c’est-à-dire qu’il renverra la valeur true pour les dates non valides également, par exemple. new Date('random_string')
est également une instance de Date
date instanceof Date
Cela échouera si les objets sont passés au-delà des limites du cadre.
Une solution pour cela consiste à vérifier la classe de l'objet via
Object.prototype.toString.call(date) === '[object Date]'
Vous pouvez utiliser le code suivant:
(myvar instanceof Date) // returns true or false
Afin de vérifier si la valeur est un type valide de l'objet JS-date standard, vous pouvez utiliser ce prédicat:
_function isValidDate(date) {
return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
_
date
vérifie si le paramètre n'était pas un valeur de fausseté (undefined
, null
, _0
_, _""
_, etc ..)Object.prototype.toString.call(date)
renvoie une représentation sous forme de chaîne native du type d'objet donné - Dans notre cas, _"[object Date]"
_. Parce que date.toString()
remplace sa méthode parente , nous devons .call
ou .apply
la méthode de _Object.prototype
_ directement qui .. instanceof
ou Date.prototype.isPrototypeOf
.!isNaN(date)
vérifie enfin si la valeur n'était pas un _Invalid Date
_.La fonction est getMonth()
et non GetMonth()
.
Quoi qu'il en soit, vous pouvez vérifier si l'objet a une propriété getMonth en procédant ainsi. Cela ne signifie pas nécessairement que l'objet est une Date, mais tout objet possédant une propriété getMonth.
if (date.getMonth) {
var month = date.getMonth();
}
Comme indiqué ci-dessus, il est probablement plus facile de vérifier si la fonction existe avant de l'utiliser. Si vous vous souciez vraiment qu'il s'agisse d'un Date
, et pas simplement d'un objet avec une fonction getMonth()
, essayez ceci:
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
Cela créera soit un clone de la valeur s'il s'agit de Date
, soit une date non valide. Vous pouvez ensuite vérifier si la valeur de la nouvelle date est invalide ou non.
Pour tous les types, j'ai concocté une fonction de prototype d'objet. Cela 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;
}
Maintenant, vous pouvez vérifier tout type comme ceci:
var myDate = new Date().toString(),
myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String
[Edit mars 201] Sur la base de la progression des connaissances, il s'agit d'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
UnderscoreJS et Lodash ont une fonction appelée .isDate()
= qui semble être exactement ce dont vous avez besoin. Cela vaut la peine de regarder leurs implémentations respectives: Lodash isDate , nderscoreJs
Le meilleur moyen que j'ai trouvé est:
!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001")) // true
!isNaN(Date.parse("blabla")) // false
Vous pouvez vérifier si une fonction spécifique à l'objet Date existe:
function getFormatedDate(date) {
if (date.getMonth) {
var month = date.getMonth();
}
}
J'ai utilisé un moyen beaucoup plus simple, mais je ne suis pas sûr si cela est uniquement disponible dans ES6 ou non.
let a = {name: "a", age: 1, date: new Date("1/2/2017"), arr: [], obj: {} };
console.log(a.name.constructor.name); // "String"
console.log(a.age.constructor.name); // "Number"
console.log(a.date.constructor.name); // "Date"
console.log(a.arr.constructor.name); // "Array"
console.log(a.obj.constructor.name); // "Object"
Cependant, cela ne fonctionnera pas sur null ou undefined car ils n'ont pas de constructeur.
Aussi, vous pouvez utiliser la forme abrégée
function getClass(obj) {
return {}.toString.call(obj).slice(8, -1);
}
alert( getClass(new Date) ); //Date
ou quelque chose comme ça:
(toString.call(date)) == 'Date'
Cette fonction retournera true
s'il s'agit de Date ou false
sinon:
function isDate(myDate) {
return myDate.constructor.toString().indexOf("Date") > -1;
}
Une approche utilisant un try/catch
function getFormatedDate(date = new Date()) {
try {
date.toISOString();
} catch (e) {
date = new Date();
}
return date;
}
console.log(getFormatedDate());
console.log(getFormatedDate('AAAA'));
console.log(getFormatedDate(new Date('AAAA')));
console.log(getFormatedDate(new Date(2018, 2, 10)));
Au lieu de toutes les solutions de contournement, vous pouvez utiliser les éléments suivants:
dateVariable = new Date(date);
if (dateVariable == 'Invalid Date') console.log('Invalid Date!');
J'ai trouvé ce bidouillage mieux!
Encore une autre variante:
Date.prototype.isPrototypeOf(myDateObject)
En fait, la date sera de type Object
. Mais vous pouvez vérifier si l'objet a la méthode getMonth
et s'il est appelable.
function getFormatedDate(date) {
if (date && date.getMonth && date.getMonth.call) {
var month = date.getMonth();
}
}