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à undefineddi 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 === undefinedpotrebbe 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 undefinedvalore speciale stesso:
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
obj !== undefinedora. undefinedera mutevole, come undefined = 1234quello 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 myVarnon viene dichiarato.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Inoltre, myVar === undefinedgenererà un errore nella situazione in cui myVar non è dichiarato.
=== undefinedconfusione. 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 Truee 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 undefinedpena considerare la possibilità di assegnare anche qui?
void 0per ottenere il valore a cui undefinedpunta. Quindi puoi farlo if (myVar === void 0). il 0non è 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 undefinede per l'esistenza di una variabile. Nella stragrande maggioranza dei casi, sai quando esiste una variabile e typeofintrodurrai 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 undefinede sono sempre nell'ambito.
che undefinedpuò essere sovrascritto. C'è molto di più in questo. undefinednon è 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 undefinedproprietà e dal 2017 questo è stato il caso per molto tempo. La mancanza di una modalità rigorosa non influisce nemmeno sul undefinedcomportamento - fa solo affermazioni come undefined = 5non fare nulla invece di lanciare. Dal momento che non è una parola chiave, tuttavia, è possibile dichiarare variabili con il nome undefinede tali variabili potrebbero essere modificate, rendendo questo modello una volta comune:
(function (undefined) {
// …
})()
più pericoloso che usare il globale undefined. Se devi essere compatibile undefinedcon 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 typeofper le proprietà degli oggetti. L'eccezione precedente relativa al rilevamento di funzionalità non si applica qui: typeofha 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 undefineddurante la lettura), presente sull'oggetto stesso con il valore undefined, presente sul prototipo dell'oggetto con il valore undefinedo presente su uno di quelli con prototipi non oggetto su MDN per più!undefined valore. 'key' in objti 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 undefinedriferisce alla undefinedproprietà dell'oggetto globale. sostituire void 0altrimenti.
undefined, nascondendo quello predefinito. Che per scopi pratici ha lo stesso effetto della sovrascrittura.
void 0confronto 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.aindefinito? Sì! Il suo valore non è definito. È o.bindefinito? 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 === undefinedsono 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 === undefinedo questo typeof x.a == 'undefined'aumenta ReferenceError: x is not definedse x non è definito.undefinedè una variabile globale (quindi in realtà è window.undefinednei 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 === undefinedvstypeof obj.prop == 'undefined'Vantaggi di obj.prop === undefined:
undefinedSvantaggi 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 undefinedcome global.undefined(può anche essere usata senza il prefisso "globale"). Non conosco altre implementazioni di JavaScript lato server.
undefinedcome 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 globalmostra 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.foonon ci dice quale dei tre casi abbiamo. Tuttavia, possiamo combinare questo con "foo" in objper 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 nullvoci
| 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 ae !('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 typeofprovenienza, 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 varper i intest 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 myvarnon 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.myvarper verificare se ha un valore corretto / valido. Quindi, anche quando la variabile non è definita, !window.myvarè uguale per myvar = undefinedo myvar = falseo 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 undefinednon è cioè mentre undefinedè uguale per void 0impostazione predefinita, è possibile assegnare un valore ad undefinedes 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 typeofche 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 typeofnel 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 typeofse 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.xrestituisce 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 truese è definito come nullo 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 trueper 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')
foonon è 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
getUndefienddovrebbe 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.
typeofguardia in realtà non protegge da nulla che un confronto diretto non possa gestire. Se restResultnon 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)
1alla variabile x? Ho bisogno di Underscore o jQuery? (sorprendente che le persone useranno le librerie anche per le operazioni più elementari come un typeofcontrollo)
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.someFieldper verificare se è definito nel dizionario. Ma possiamo usare thiso windowcome 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 abcnon è 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
}
typeoftest in una funzione. Incredibile che 4 persone abbiano votato per questo. -1.
Vorrei mostrarti qualcosa che sto usando per proteggere la undefinedvariabile:
Object.defineProperty(window, 'undefined', {});
Ciò vieta a chiunque di modificare il window.undefinedvalore, 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
}