Qual è il modo migliore per verificare se una proprietà dell'oggetto in JavaScript è undefined
?
Qual è il modo migliore per verificare se una proprietà dell'oggetto in JavaScript è undefined
?
Risposte:
Il solito modo per verificare se il valore di una proprietà è il valore speciale undefined
è:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
Per verificare se un oggetto non ha effettivamente una tale proprietà e, pertanto, tornerà undefined
di default quando si tenta di accedervi:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
Per verificare se il valore associato a un identificatore è il valore speciale undefined
, o se tale identificatore non è stato dichiarato. Nota: questo metodo è l'unico modo per fare riferimento a un identificatore non dichiarato (nota: diverso dall'avere un valore di undefined
) senza un errore iniziale:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
Nelle versioni di JavaScript precedenti a ECMAScript 5, la proprietà denominata "non definita" sull'oggetto globale era scrivibile e quindi un semplice controllo foo === undefined
potrebbe comportarsi in modo imprevisto se fosse stato ridefinito accidentalmente. Nel moderno JavaScript, la proprietà è di sola lettura.
Tuttavia, nel JavaScript moderno, "non definito" non è una parola chiave, quindi le variabili all'interno delle funzioni possono essere denominate "non definite" e oscurare la proprietà globale.
Se sei preoccupato per questo (improbabile) caso limite, puoi usare l'operatore vuoto per ottenere il undefined
valore speciale stesso:
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
obj !== undefined
ora. undefined
era mutevole, come undefined = 1234
quello che avrebbe causato risultati interessanti. Ma dopo Ecmascript 5, non è più scrivibile, quindi possiamo usare la versione più semplice. codereadability.com/how-to-check-for-undefined-in-javascript
Credo che ci siano diverse risposte errate a questo argomento. Contrariamente alla credenza comune, "undefined" non è una parola chiave in JavaScript e può infatti avere un valore assegnato ad essa.
Il modo più efficace per eseguire questo test è:
if (typeof myVar === "undefined")
Ciò restituirà sempre il risultato corretto e gestisce anche la situazione in cui myVar
non viene dichiarato.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Inoltre, myVar === undefined
genererà un errore nella situazione in cui myVar non è dichiarato.
=== undefined
confusione. Sì, puoi assegnarlo a undefined
, ma non esiste un motivo legittimo per farlo ed è prevedibile che ciò possa violare il tuo codice. In C puoi #define true false
, e in Python puoi assegnare a True
e False
, ma le persone non sentono il bisogno di progettare il loro codice in quelle lingue in modo tale da proteggersi contro la possibilità di sabotare deliberatamente il proprio ambiente altrove nel codice . Perché vale la undefined
pena considerare la possibilità di assegnare anche qui?
void 0
per ottenere il valore a cui undefined
punta. Quindi puoi farlo if (myVar === void 0)
. il 0
non è speciale, si può letteralmente mettere qualsiasi espressione lì.
undefined
. MDN: non definito
Nonostante sia raccomandato con veemenza da molte altre risposte qui, typeof
è una cattiva scelta . Non dovrebbe mai essere usato per verificare se le variabili hanno il valore undefined
, perché funge da controllo combinato per il valore undefined
e per l'esistenza di una variabile. Nella stragrande maggioranza dei casi, sai quando esiste una variabile e typeof
introdurrai il potenziale per un errore silenzioso se fai un errore di battitura nel nome della variabile o nella stringa letterale 'undefined'
.
var snapshot = …;
if (typeof snaposhot === 'undefined') {
// ^
// misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;
if (typeof foo === 'undefned') {
// ^
// misspelled – this will never run, but it won’t throw an error!
}
Quindi, a meno che tu non stia eseguendo il rilevamento delle funzionalità², dove non vi è incertezza sul fatto che un determinato nome sia compreso nell'ambito (come il controllo typeof module !== 'undefined'
compreso come passaggio nel codice specifico di un ambiente CommonJS), typeof
è una scelta dannosa se utilizzato su una variabile e l'opzione corretta è per confrontare direttamente il valore:
var foo = …;
if (foo === undefined) {
⋮
}
Alcune idee sbagliate comuni su questo includono:
che la lettura di una variabile (non inizializzata var foo
) ( ) o parametro (function bar(foo) { … }
, chiamato come bar()
) fallirà. Questo semplicemente non è vero: le variabili senza inizializzazione esplicita e i parametri a cui non sono stati dati i valori diventano sempre undefined
e sono sempre nell'ambito.
che undefined
può essere sovrascritto. C'è molto di più in questo. undefined
non è una parola chiave in JavaScript. Invece, è una proprietà sull'oggetto globale con il valore Non definito. Tuttavia, da ES5, questa proprietà è stata di sola lettura e non configurabile . Nessun browser moderno consentirà di modificare la undefined
proprietà e dal 2017 questo è stato il caso per molto tempo. La mancanza di una modalità rigorosa non influisce nemmeno sul undefined
comportamento - fa solo affermazioni come undefined = 5
non fare nulla invece di lanciare. Dal momento che non è una parola chiave, tuttavia, è possibile dichiarare variabili con il nome undefined
e tali variabili potrebbero essere modificate, rendendo questo modello una volta comune:
(function (undefined) {
// …
})()
più pericoloso che usare il globale undefined
. Se devi essere compatibile undefined
con ES3, sostituiscilo con void 0
- non ricorrere a typeof
. ( void
è sempre stato un operatore unario che valuta il valore Non definito per qualsiasi operando.)
Con il modo in cui le variabili funzionano, è il momento di rispondere alla domanda effettiva: proprietà dell'oggetto. Non c'è motivo di utilizzare mai typeof
per le proprietà degli oggetti. L'eccezione precedente relativa al rilevamento di funzionalità non si applica qui: typeof
ha solo un comportamento speciale sulle variabili e le espressioni che fanno riferimento alle proprietà degli oggetti non sono variabili.
Questo:
if (typeof foo.bar === 'undefined') {
⋮
}
è sempre esattamente equivalente a questo³:
if (foo.bar === undefined) {
⋮
}
e tenendo conto dei consigli di cui sopra, per evitare di confondere i lettori sul perché stai usando typeof
, perché ha più senso usare ===
per verificare l'uguaglianza, perché potrebbe essere rifattorizzato per controllare il valore di una variabile in un secondo momento, e perché semplicemente sembra migliore, dovresti sempre usare anche === undefined
³ anche qui .
Qualcos'altro da considerare quando si tratta di proprietà degli oggetti è se si vuole davvero controllare undefined
. Un determinato nome di proprietà può essere assente su un oggetto (producendo il valore undefined
durante la lettura), presente sull'oggetto stesso con il valore undefined
, presente sul prototipo dell'oggetto con il valore undefined
o presente su uno di quelli con prototipi non oggetto su MDN per più!undefined
valore. 'key' in obj
ti dirà se una chiave si trova ovunque nella catena di prototipi di un oggetto e Object.prototype.hasOwnProperty.call(obj, 'key')
ti dirà se si trova direttamente sull'oggetto. Non entrerò nei dettagli in questa risposta sui prototipi e sull'uso di oggetti come mappe con stringhe di chiavi, perché è principalmente inteso a contrastare tutti i cattivi consigli in altre risposte, indipendentemente dalle possibili interpretazioni della domanda originale. Leggere su
¹ insolita scelta del nome della variabile di esempio? questo è un vero codice morto dall'estensione NoScript per Firefox.
² Non dare per scontato che non sapere cosa rientri nel campo di applicazione va bene in generale. vulnerabilità del bonus causata dall'abuso di ambito dinamico: Project Zero 1225
³ ancora una volta assumendo un ambiente ES5 + e che si undefined
riferisce alla undefined
proprietà dell'oggetto globale. sostituire void 0
altrimenti.
undefined
, nascondendo quello predefinito. Che per scopi pratici ha lo stesso effetto della sovrascrittura.
void 0
confronto con indefinito, ma ancora una volta - è sciocco e eccessivo.
typeof something === "undefined")
nel codice.
void 0
è (per una volta) sia più breve che più sicuro! Questa è una vittoria nel mio libro.
In JavaScript c'è null e non è definito . Hanno significati diversi.
Marijn Haverbeke afferma, nel suo libro online gratuito " Eloquent JavaScript " (sottolineatura mia):
Esiste anche un valore simile, null, il cui significato è "questo valore è definito, ma non ha un valore". La differenza di significato tra indefinito e nullo è per lo più accademica e di solito non molto interessante. Nei programmi pratici, è spesso necessario verificare se qualcosa "ha un valore". In questi casi, è possibile utilizzare l'espressione qualcosa == indefinito, perché, anche se non hanno esattamente lo stesso valore, null == indefinito produrrà vero.
Quindi, immagino che il modo migliore per verificare se qualcosa non era definito sarebbe:
if (something == undefined)
Spero che sia di aiuto!
Modifica: in risposta alla modifica, le proprietà degli oggetti dovrebbero funzionare allo stesso modo.
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
undefined
è solo una variabile che può essere riassegnata dall'utente: la scrittura undefined = 'a';
farà sì che il tuo codice non faccia più ciò che pensi che faccia. L'uso typeof
è migliore e funziona anche per variabili (non solo proprietà) che non sono state dichiarate.
Cosa significa: "proprietà dell'oggetto non definito" ?
In realtà può significare due cose abbastanza diverse! Innanzitutto, può indicare la proprietà che non è mai stata definita nell'oggetto e, in secondo luogo, può indicare la proprietà che ha un valore indefinito . Diamo un'occhiata a questo codice:
var o = { a: undefined }
È o.a
indefinito? Sì! Il suo valore non è definito. È o.b
indefinito? Sicuro! Non esiste alcuna proprietà "b"! OK, vedi ora come si comportano approcci diversi in entrambe le situazioni:
typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false
Possiamo vederlo chiaramente typeof obj.prop == 'undefined'
e obj.prop === undefined
sono equivalenti e non distinguono queste diverse situazioni. E'prop' in obj
può rilevare la situazione quando una proprietà non è stata definita affatto e non presta attenzione al valore della proprietà che potrebbe non essere definito.
1) Vuoi sapere se una proprietà non è definita dal primo o dal secondo significato (la situazione più tipica).
obj.prop === undefined // IMHO, see "final fight" below
2) Vuoi solo sapere se l'oggetto ha delle proprietà e non ti interessa il suo valore.
'prop' in obj
x.a === undefined
o questo typeof x.a == 'undefined'
aumenta ReferenceError: x is not defined
se x non è definito.undefined
è una variabile globale (quindi in realtà è window.undefined
nei browser). E 'stato sostenuto dal ECMAScript Edition 1 ° e dal momento ECMAScript 5 è in sola lettura . Quindi nei browser moderni non può essere ridefinito come vero poiché molti autori amano spaventarci, ma questo è ancora vero per i browser più vecchi.obj.prop === undefined
vstypeof obj.prop == 'undefined'
Vantaggi di obj.prop === undefined
:
undefined
Svantaggi di obj.prop === undefined
:
undefined
può essere sostituito nei vecchi browserVantaggi di typeof obj.prop == 'undefined'
:
Svantaggi di typeof obj.prop == 'undefined'
:
'undefned'
( errato ) qui è solo una costante di stringa, quindi il motore JavaScript non può aiutarti se l'hai scritto male come ho appena fatto.Node.js supporta la variabile globale undefined
come global.undefined
(può anche essere usata senza il prefisso "globale"). Non conosco altre implementazioni di JavaScript lato server.
undefined
come membro di global
. Inoltre, né console.log(global);
né for (var key in global) { ... }
mostra non definito come membro del globale . Ma prova come 'undefined' in global
mostra il contrario.
[[Enumerable]]
è falso :-)
Minuses of typeof obj.prop == 'undefined'
, questo può essere evitato scrivendo come typeof obj.prop == typeof undefined
. Questo dà anche una simmetria molto bella.
obj.prop === undefined
.
if ('foo' in o
) ... la tua risposta è davvero la prima risposta corretta qui. Praticamente tutti gli altri rispondono solo a quella frase.
Il problema si riduce a tre casi:
undefined
.undefined
.Questo ci dice qualcosa che considero importante:
Esiste una differenza tra un membro non definito e un membro definito con un valore non definito.
Ma purtroppo typeof obj.foo
non ci dice quale dei tre casi abbiamo. Tuttavia, possiamo combinare questo con "foo" in obj
per distinguere i casi.
| typeof obj.x === 'undefined' | !("x" in obj)
1. { x:1 } | false | false
2. { x : (function(){})() } | true | false
3. {} | true | true
Vale la pena notare che questi test sono gli stessi anche per le null
voci
| typeof obj.x === 'undefined' | !("x" in obj)
{ x:null } | false | false
Direi che in alcuni casi ha più senso (ed è più chiaro) verificare se la proprietà è presente, piuttosto che verificare se non è definita, e l'unico caso in cui questo controllo sarà diverso è il caso 2, il raro caso di una voce effettiva nell'oggetto con un valore indefinito.
Ad esempio: ho appena eseguito il refactoring di un gruppo di codice che aveva un sacco di controlli se un oggetto avesse una determinata proprietà.
if( typeof blob.x != 'undefined' ) { fn(blob.x); }
Che era più chiaro se scritto senza un segno di spunta per indefinito.
if( "x" in blob ) { fn(blob.x); }
Ma come è stato menzionato, questi non sono esattamente gli stessi (ma sono più che sufficienti per le mie esigenze).
if (!("x" in blob)) {}
con parentesi attorno a in, perché il! l'operatore ha la precedenza su "in". Spero che aiuti qualcuno.
a = {b: undefined}
; allora typeof a.b === typeof a.c === 'undefined'
ma 'b' in a
e !('c' in a)
.
{ x : undefined }
o almeno aggiungerlo come un'altra alternativa a (2.) nella tabella - Ho dovuto pensare per un momento a rendermi conto che il punto (2.) valuta undefined
(sebbene lo dici più avanti).
if ( typeof( something ) == "undefined")
Questo ha funzionato per me mentre gli altri no.
typeof (something == "undefined")
.
(typeof something) === "undefined"
.
Io non sono sicuro di dove l'origine di utilizzare ===
con typeof
provenienza, e come una convenzione vedo io usato in molte biblioteche, ma l'operatore typeof restituisce una stringa letterale, e sappiamo che davanti, in modo perché si vuole anche per tipo controlla anche tu?
typeof x; // some string literal "string", "object", "undefined"
if (typeof x === "string") { // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") { // sufficient
==
richiede ancora almeno un controllo del tipo: l'interprete non può confrontare i due operandi senza prima conoscerne il tipo.
==
è un personaggio in meno di ===
:)
Crossposting della mia risposta dalla domanda correlata Come verificare la presenza di "non definito" in JavaScript?
Specifico per questa domanda, vedere i casi di test con someObject.<whatever>
.
Alcuni scenari che illustrano i risultati delle varie risposte: http://jsfiddle.net/drzaus/UVjM4/
(Si noti che l'uso di var
per i in
test fa la differenza in un wrapper con ambito)
Codice di riferimento:
(function(undefined) {
var definedButNotInitialized;
definedAndInitialized = 3;
someObject = {
firstProp: "1"
, secondProp: false
// , undefinedProp not defined
}
// var notDefined;
var tests = [
'definedButNotInitialized in window',
'definedAndInitialized in window',
'someObject.firstProp in window',
'someObject.secondProp in window',
'someObject.undefinedProp in window',
'notDefined in window',
'"definedButNotInitialized" in window',
'"definedAndInitialized" in window',
'"someObject.firstProp" in window',
'"someObject.secondProp" in window',
'"someObject.undefinedProp" in window',
'"notDefined" in window',
'typeof definedButNotInitialized == "undefined"',
'typeof definedButNotInitialized === typeof undefined',
'definedButNotInitialized === undefined',
'! definedButNotInitialized',
'!! definedButNotInitialized',
'typeof definedAndInitialized == "undefined"',
'typeof definedAndInitialized === typeof undefined',
'definedAndInitialized === undefined',
'! definedAndInitialized',
'!! definedAndInitialized',
'typeof someObject.firstProp == "undefined"',
'typeof someObject.firstProp === typeof undefined',
'someObject.firstProp === undefined',
'! someObject.firstProp',
'!! someObject.firstProp',
'typeof someObject.secondProp == "undefined"',
'typeof someObject.secondProp === typeof undefined',
'someObject.secondProp === undefined',
'! someObject.secondProp',
'!! someObject.secondProp',
'typeof someObject.undefinedProp == "undefined"',
'typeof someObject.undefinedProp === typeof undefined',
'someObject.undefinedProp === undefined',
'! someObject.undefinedProp',
'!! someObject.undefinedProp',
'typeof notDefined == "undefined"',
'typeof notDefined === typeof undefined',
'notDefined === undefined',
'! notDefined',
'!! notDefined'
];
var output = document.getElementById('results');
var result = '';
for(var t in tests) {
if( !tests.hasOwnProperty(t) ) continue; // bleh
try {
result = eval(tests[t]);
} catch(ex) {
result = 'Exception--' + ex;
}
console.log(tests[t], result);
output.innerHTML += "\n" + tests[t] + ": " + result;
}
})();
E risultati:
definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
Se fate
if (myvar == undefined )
{
alert('var does not exists or is not initialized');
}
fallirà quando la variabile myvar
non esiste, perché myvar non è definito, quindi lo script è rotto e il test non ha alcun effetto.
Poiché l'oggetto window ha un ambito globale (oggetto predefinito) al di fuori di una funzione, una dichiarazione verrà "allegata" all'oggetto window.
Per esempio:
var myvar = 'test';
La variabile globale myvar è la stessa di window.myvar o window ['myvar']
Per evitare errori da testare quando esiste una variabile globale, è meglio usare:
if(window.myvar == undefined )
{
alert('var does not exists or is not initialized');
}
La domanda se esiste davvero una variabile non ha importanza, il suo valore non è corretto. Altrimenti, è sciocco inizializzare le variabili con undefined, ed è meglio usare il valore false per inizializzare. Quando sai che tutte le variabili che dichiari sono inizializzate con false, puoi semplicemente verificarne il tipo o fare affidamento !window.myvar
per verificare se ha un valore corretto / valido. Quindi, anche quando la variabile non è definita, !window.myvar
è uguale per myvar = undefined
o myvar = false
o myvar = 0
.
Quando ti aspetti un tipo specifico, prova il tipo di variabile. Per accelerare il test di una condizione è meglio fare:
if( !window.myvar || typeof window.myvar != 'string' )
{
alert('var does not exists or is not type of string');
}
Quando la prima e semplice condizione è vera, l'interprete salta i test successivi.
È sempre meglio usare l'istanza / oggetto della variabile per verificare se ha ottenuto un valore valido. È più stabile ed è un modo migliore di programmare.
(Y)
Non ho visto (spero di non essermi perso) nessuno che controllava l'oggetto prima della proprietà. Quindi, questo è il più breve ed efficace (anche se non necessariamente il più chiaro):
if (obj && obj.prop) {
// Do something;
}
Se obj o obj.prop è indefinito, null o "falsy", l'istruzione if non eseguirà il blocco di codice. Questo è generalmente il comportamento desiderato nella maggior parte delle istruzioni di blocco di codice (in JavaScript).
var x = obj && obj.prop || 'default';
Nell'articolo Exploring the Abyss of Null and Undefined in JavaScript ho letto che framework come Underscore.js usano questa funzione:
function isUndefined(obj){
return obj === void 0;
}
void 0
è solo un modo breve di scrivere undefined
(dato che è ciò che il vuoto seguito da qualsiasi espressione restituisce), salva 3 caratteri. Potrebbe anche fare var a; return obj === a;
, ma questo è un altro personaggio. :-)
void
è una parola riservata, mentre undefined
non è cioè mentre undefined
è uguale per void 0
impostazione predefinita, è possibile assegnare un valore ad undefined
es undefined = 1234
.
isUndefined(obj)
: 16 caratteri. obj === void 0
: 14 caratteri. 'ha detto nough.
Semplicemente qualsiasi cosa non è definita in JavaScript, non è definita , non importa se si tratta di una proprietà all'interno di un oggetto / matrice o come una semplice variabile ...
JavaScript ha typeof
che rende molto facile rilevare una variabile non definita.
Basta controllare se typeof whatever === 'undefined'
e restituirà un valore booleano.
Ecco come isUndefined()
è scritta la famosa funzione in AngularJs v.1x:
function isUndefined(value) {return typeof value === 'undefined';}
Così come vedi la funzione riceve un valore, se quel valore è definito, ritornerà false
, altrimenti restituisce valori non definiti true
.
Quindi diamo un'occhiata a quali saranno i risultati quando passiamo i valori, comprese le proprietà degli oggetti come di seguito, questo è l'elenco delle variabili che abbiamo:
var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;
e li controlliamo come di seguito, puoi vedere i risultati davanti a loro come un commento:
isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true
Come vedi possiamo controllare qualsiasi cosa usando qualcosa di simile nel nostro codice, come detto puoi semplicemente usare typeof
nel tuo codice, ma se lo usi più e più volte, crea una funzione come il campione angolare che condivido e continui a riutilizzare come seguendo il modello di codice DRY.
Inoltre, per verificare la proprietà di un oggetto in un'applicazione reale di cui non si è certi che esista o meno l'oggetto, verificare se l'oggetto esiste per primo.
Se si controlla una proprietà su un oggetto e l'oggetto non esiste, verrà generato un errore e verrà interrotta l'intera applicazione.
isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)
Così semplice che puoi avvolgere in un'istruzione if come di seguito:
if(typeof x !== 'undefined') {
//do something
}
Che equivale anche a isDefined in Angular 1.x ...
function isDefined(value) {return typeof value !== 'undefined';}
Anche altri framework javascript come underscore hanno un controllo di definizione simile, ma ti consiglio di usare typeof
se non usi già alcun framework.
Aggiungo anche questa sezione da MDN che contiene informazioni utili su typeof, undefined e void (0).
Uguaglianza rigorosa e non definita
È possibile utilizzare operatori di uguaglianza e disuguaglianza non definiti e rigorosi per determinare se una variabile ha un valore. Nel codice seguente, la variabile x non è definita e l'istruzione if restituisce true.
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
Nota: l'operatore di uguaglianza rigorosa anziché l'operatore di uguaglianza standard deve essere utilizzato qui, perché x == undefined controlla anche se x è null, mentre l'uguaglianza rigorosa no. null non equivale a undefined. Vedi gli operatori di confronto per i dettagli.
Tipo di operatore e non definito
In alternativa, è possibile utilizzare il tipo di:
var x;
if (typeof x === 'undefined') {
// these statements execute
}
Un motivo per utilizzare typeof è che non genera un errore se la variabile non è stata dichiarata.
// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
// these statements execute
}
if (x === undefined) { // throws a ReferenceError
}
Tuttavia, questo tipo di tecnica dovrebbe essere evitato. JavaScript è un linguaggio con ambito statico, quindi è possibile leggere se viene dichiarata una variabile verificando se è dichiarata in un contesto chiuso. L'unica eccezione è l'ambito globale, ma l'ambito globale è associato all'oggetto globale, pertanto è possibile verificare l'esistenza di una variabile nel contesto globale verificando l'esistenza di una proprietà sull'oggetto globale (utilizzando l'operatore in, per esempio).
Operatore del vuoto e non definito
L'operatore vuoto è una terza alternativa.
var x;
if (x === void 0) {
// these statements execute
}
// y has not been declared before
if (y === void 0) {
// throws a ReferenceError (in contrast to `typeof`)
}
altro> qui
Molto probabilmente lo vuoi if (window.x)
. Questo controllo è sicuro anche se x non è stato dichiarato ( var x;
) - il browser non genera un errore.
if (window.history) {
history.call_some_function();
}
window è un oggetto che contiene tutte le variabili globali come membri ed è legale tentare di accedere a un membro inesistente. Se x non è stato dichiarato o non è stato impostato, window.x
restituisce un valore non definito . undefined porta a false quando if () lo valuta.
typeof history != 'undefined'
funziona effettivamente in entrambi i sistemi.
Leggendo questo, sono stupito di non averlo visto. Ho trovato più algoritmi che avrebbero funzionato per questo.
Se il valore di un oggetto non è mai stato definito, ciò impedirà la restituzione true
se è definito come null
o undefined
. Ciò è utile se si desidera che true venga restituito per i valori impostati comeundefined
if(obj.prop === void 0) console.log("The value has never been defined");
Se vuoi che risulti come true
per i valori definiti con il valore di undefined
, o mai definiti, puoi semplicemente usare=== undefined
if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");
Comunemente, le persone mi hanno chiesto un algoritmo per capire se un valore è falso undefined
, o null
. I seguenti lavori.
if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
console.log("The value is falsy, null, or undefined");
}
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
-> true
. Come è "mai definito come undefined
"? Questo è sbagliato.
Confronta con void 0
, per terseness.
if (foo !== void 0)
Non è così prolisso come if (typeof foo !== 'undefined')
foo
non è dichiarato.
La soluzione non è corretta In JavaScript,
null == undefined
tornerà vero, perché entrambi sono "espressi" in un valore booleano e sono falsi. Il modo corretto sarebbe quello di verificare
if (something === undefined)
che è l'operatore di identità ...
===
è tipo uguaglianza + (uguaglianza primitiva | identità dell'oggetto), dove le primitive includono stringhe. Penso che molte persone considerino 'abab'.slice(0,2) === 'abab'.slice(2)
non intuitivo se si considera ===
l'operatore di identità.
È possibile ottenere un array tutto non definito con percorso utilizzando il seguente codice.
function getAllUndefined(object) {
function convertPath(arr, key) {
var path = "";
for (var i = 1; i < arr.length; i++) {
path += arr[i] + "->";
}
path += key;
return path;
}
var stack = [];
var saveUndefined= [];
function getUndefiend(obj, key) {
var t = typeof obj;
switch (t) {
case "object":
if (t === null) {
return false;
}
break;
case "string":
case "number":
case "boolean":
case "null":
return false;
default:
return true;
}
stack.push(key);
for (k in obj) {
if (obj.hasOwnProperty(k)) {
v = getUndefiend(obj[k], k);
if (v) {
saveUndefined.push(convertPath(stack, k));
}
}
}
stack.pop();
}
getUndefiend({
"": object
}, "");
return saveUndefined;
}
Collegamento jsFiddle
getUndefiend
dovrebbe essere getUndefined
.
Ecco la mia situazione:
Sto usando il risultato di una chiamata REST. Il risultato deve essere analizzato da JSON a un oggetto JavaScript.
C'è un errore che devo difendere. Se l'args alla chiamata di riposo era errato per quanto l'utente specificava l'args errata, la chiamata di riposo ritorna sostanzialmente vuota.
Durante l'utilizzo di questo post per aiutarmi a difendermi da questo, ho provato questo.
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
Per la mia situazione, se restResult.data [0] === "oggetto", posso tranquillamente iniziare a ispezionare il resto dei membri. Se non definito, gettare l'errore come sopra.
Quello che sto dicendo è che per la mia situazione, tutti i suggerimenti sopra riportati in questo post non hanno funzionato. Non sto dicendo che ho ragione e tutti hanno torto. Non sono affatto un maestro JavaScript, ma spero che questo possa aiutare qualcuno.
typeof
guardia in realtà non protegge da nulla che un confronto diretto non possa gestire. Se restResult
non definito o non dichiarato, verrà comunque lanciato.
if(!restResult.data.length) { throw "Some error"; }
Esiste un modo semplice ed elegante per assegnare una proprietà definita a una nuova variabile se è definita o assegnare un valore predefinito ad essa come fallback se non definito.
var a = obj.prop || defaultValue;
È adatto se si dispone di una funzione, che riceve una proprietà di configurazione aggiuntiva:
var yourFunction = function(config){
this.config = config || {};
this.yourConfigValue = config.yourConfigValue || 1;
console.log(this.yourConfigValue);
}
Ora in esecuzione
yourFunction({yourConfigValue:2});
//=> 2
yourFunction();
//=> 1
yourFunction({otherProperty:5});
//=> 1
Tutte le risposte sono incomplete. Questo è il modo giusto di sapere che esiste una proprietà "definita come non definita":
var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;
Esempio:
var a = { b : 1, e : null } ;
a.c = a.d ;
hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null
// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined
Peccato che questa sia la risposta giusta sia sepolta in risposte sbagliate> _ <
Quindi, per chiunque passi, ti darò gratuitamente undefined !!
var undefined ; undefined ; // undefined
({}).a ; // undefined
[].a ; // undefined
''.a ; // undefined
(function(){}()) ; // undefined
void(0) ; // undefined
eval() ; // undefined
1..a ; // undefined
/a/.a ; // undefined
(true).a ; // undefined
Passando attraverso i commenti, per coloro che vogliono controllare entrambi è indefinito o il suo valore è nullo:
//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
alert('either it is undefined or value is null')
}
Se stai utilizzando la libreria jQuery, jQuery.isEmptyObject()
sarà sufficiente per entrambi i casi,
var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;
s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;
//Usage
if (jQuery.isEmptyObject(s)) {
alert('Either variable:s is undefined or its value is null');
} else {
alert('variable:s has value ' + s);
}
s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
Se si utilizza Angular:
angular.isUndefined(obj)
angular.isUndefined(obj.prop)
Underscore.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
1
alla variabile x
? Ho bisogno di Underscore o jQuery? (sorprendente che le persone useranno le librerie anche per le operazioni più elementari come un typeof
controllo)
Uso if (this.variable)
per verificare se è definito. Semplice if (variable)
, consigliato sopra , fallisce per me. Si scopre che funziona solo quando la variabile è un campo di un oggetto, obj.someField
per verificare se è definito nel dizionario. Ma possiamo usare this
o window
come oggetto dizionario poiché qualsiasi variabile è un campo nella finestra corrente, a quanto ho capito. Pertanto, ecco un test
if (this.abc) alert("defined"); else alert("undefined");
abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");
Rileva innanzitutto che la variabile abc
non è definita e viene definita dopo l'inizializzazione.
Fornisco tre modi qui per coloro che si aspettano risposte strane:
function isUndefined1(val) {
try {
val.a;
} catch (e) {
return /undefined/.test(e.message);
}
return false;
}
function isUndefined2(val) {
return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
const defaultVal={};
return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
console.group(`test start :`+func.name);
console.log(func(undefined));
console.log(func(null));
console.log(func(1));
console.log(func("1"));
console.log(func(0));
console.log(func({}));
console.log(func(function () { }));
console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);
Prova a ottenere una proprietà del valore di input, controlla il messaggio di errore se esiste. Se il valore di input non è definito, il messaggio di errore sarebbe Uncaught TypeError: Impossibile leggere la proprietà 'b' di undefined
Converti il valore di input in stringa per confrontarlo "undefined"
e assicurati che sia un valore negativo.
In js, il parametro opzionale funziona quando il valore di input è esattamente undefined
.
ES2019 ha introdotto una nuova funzione - concatenamento opzionale che è possibile utilizzare per utilizzare una proprietà di un oggetto solo quando un oggetto è definito in questo modo:
const userPhone = user?.contactDetails?.phone;
Si farà riferimento alla proprietà del telefono solo quando sono definiti user e contactDetails.
Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Restituisce false se la variabile è impostata e true se non è definito.
Quindi utilizzare:
if (isUnset(var)) {
// initialize variable here
}
typeof
test in una funzione. Incredibile che 4 persone abbiano votato per questo. -1.
Vorrei mostrarti qualcosa che sto usando per proteggere la undefined
variabile:
Object.defineProperty(window, 'undefined', {});
Ciò vieta a chiunque di modificare il window.undefined
valore, distruggendo quindi il codice basato su quella variabile. Se si utilizza "use strict"
, qualsiasi cosa che provi a modificarne il valore finirà per errore, altrimenti verrebbe ignorato silenziosamente.
puoi anche usare Proxy, funzionerà con le chiamate nidificate, ma richiederà un controllo extra:
function resolveUnknownProps(obj, resolveKey) {
const handler = {
get(target, key) {
if (
target[key] !== null &&
typeof target[key] === 'object'
) {
return resolveUnknownProps(target[key], resolveKey);
} else if (!target[key]) {
return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
}
return target[key];
},
};
return new Proxy(obj, handler);
}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }
quindi lo userai come:
const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
// do someting
}