javascript - Hvordan sjekke om et objekt er en dato?
Jeg har en irriterende feil på en nettside:
date.GetMonth() er ikke en funksjon
Så, jeg antar at jeg gjør noe galt. Variabelen date er ikke et objekt av typen Date. Hvordan kan jeg sjekke for en datatype i Javascript? Jeg prøvde å legge til en if (date), men det fungerer ikke.
function getFormatedDate(date) {
if (date) {
var month = date.GetMonth();
}
}
Så, hvis jeg vil skrive defensiv kode og forhindre at datoen (som ikke er en) blir formatert, hvordan gjør jeg det?
Takk!
OPPDATERING: Jeg vil ikke sjekke formatet på datoen, men jeg vil være sikker på at parameteren som sendes til metoden getFormatedDate() er av typen Date.
Svar #1
Som et alternativ til ande-typing via
typeof date.getMonth === 'function'
du kan bruke instanceof-operatoren, det vil si. Men den vil også returnere true for ugyldige datoer, f.eks. new Date('random_string') er også en instans av Date
date instanceof Date
Dette vil mislykkes hvis objekter blir sendt over rammgrenser.
En måte å omgå dette på er å sjekke objektets klasse via
Object.prototype.toString.call(date) === '[object Date]'
Vær oppmerksom på at instanceof-løsningen ikke fungerer når du bruker flere domener:
JavaScript-eksekveringsmiljøer (vinduer, rammer, osv.) er hver i sitt eget rike. Dette betyr at de har forskjellige innebygde elementer (forskjellig globalt objekt, forskjellige konstruktører, osv.). Dette kan føre til uventede resultater. For eksempel vil [] instanceof window.frames[0].Array returnere false, fordi Array.prototype !== window.frames[0].Array.prototype, og arrays i det nåværende riket arver fra førstnevnte.
Svar #2
Du kan bruke følgende kode:
(myvar instanceof Date) // returns true or false
Vær oppmerksom på at denne løsningen ikke fungerer når du bruker flere domener:
JavaScript-eksekveringsmiljøer (vinduer, rammer, osv.) er hver i sitt eget rike. Dette betyr at de har forskjellige innebygde elementer (forskjellig globalt objekt, forskjellige konstruktører, osv.). Dette kan føre til uventede resultater. For eksempel vil [] instanceof window.frames[0].Array returnere false, fordi Array.prototype !== window.frames[0].Array.prototype, og arrays i det nåværende riket arver fra førstnevnte.
Svar #3
For å sjekke om verdien er en gyldig type av standard JS-datoobjekt, kan du bruke denne predikatet:
function isValidDate(date) {
return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
datesjekker om parameteren ikke var en falsk verdi (undefined,null,0,"", osv..)Object.prototype.toString.call(date)returnerer en native strengrepresentasjon av den gitte objekttypen - I vårt tilfelle"[object Date]". Fordidate.toString()overstyrer sin foreldremetode, må vi.calleller.applymetoden fraObject.prototypedirekte som ..- Omgår brukerdefinert objekttype med samme konstruktørnavn (f.eks.: "Date")
- Fungerer på tvers av ulike JS-kontekster (f.eks. iframes) i motsetning til
instanceofellerDate.prototype.isPrototypeOf. !isNaN(date)sjekker til slutt om verdien ikke var enInvalid Date.
Svar #4
Funksjonen er getMonth(), ikke GetMonth().
Uansett, du kan sjekke om objektet har en getMonth-egenskap ved å gjøre dette. Det betyr ikke nødvendigvis at objektet er en Date, bare et hvilket som helst objekt som har en getMonth-egenskap.
if (date.getMonth) {
var month = date.getMonth();
}
Svar #5
Dette er en ganske enkel tilnærming hvis du ikke er bekymret for iframes/andre kontekster.
// isNaN(Invalid Date) == true
if (date instanceof Date && !isNaN(date)) { // isNaN wont accept a date in typescript, use date.getTime() instead to produce a number
console.log("is date!");
}
- Sjekker om objektet faktisk er en
Dateog ikke noe som bare ser ut som en. Enhver gjenstand kan ha engetMonth-funksjon. - Sikrer at datoen ikke er en
ugyldig dato - Sender ikke inn en verdi til
new Date()der et tall eller til og med en streng kunne bli gjort om til en Date.
Hvis du trenger å støtte iframes og forskjellige kontekster, kan du bruke det aksepterte svaret, men legg til en ekstra sjekk for å identifisere ugyldige datoer.
// isNaN(Invalid Date) == true
if (Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date)) {
console.log("is date!");
}
Svar #6
Som angitt ovenfor, er det sannsynligvis enklest å bare sjekke om funksjonen eksisterer før du bruker den. Hvis du virkelig bryr deg om at det er en Date, og ikke bare et objekt med en getMonth()-funksjon, prøv dette:
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
Dette vil enten lage en klone av verdien hvis det er en Date, eller lage en ugyldig dato. Du kan deretter sjekke om den nye datoens verdi er ugyldig eller ikke.
Svar #7
For alle typer laget jeg en objektprototype-funksjon. Den kan være nyttig for deg
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;
}
Nå kan du sjekke hvilken som helst type på denne måten:
var myDate = new Date().toString(),
myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String
[Redigert mars 2013] basert på økende innsikt er dette en bedre metode:
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
Svar #8
Den beste måten jeg har funnet er:
!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001")) // true
!isNaN(Date.parse("blabla")) // false
Svar #9
UnderscoreJS og Lodash har en funksjon kalt .isDate() som ser ut til å være akkurat det du trenger. Det er verdt å se på deres respektive implementasjoner: Lodash isDate, UnderscoreJs
