Domanda Rilevazione di una proprietà dell'oggetto non definita


Qual è il modo migliore per verificare se una proprietà dell'oggetto in JavaScript non è definita?


2430
2017-08-26 07:25


origine


risposte:


Uso:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Se una variabile oggetto che ha alcune proprietà puoi usare la stessa cosa in questo modo:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

Dal momento che ECMAScript 5, undefined non può essere sovrascritto, quindi my_obj === undefined funzionerebbe anche, ma solo se my_obj esiste. Questo può o non può essere desiderato perché puoi anche usarlo null se hai bisogno di questo semantico (vedi Qual è la differenza tra null e undefined in JavaScript?). Per le proprietà degli oggetti, tuttavia, funziona indipendentemente dal fatto che la proprietà esista.


2316
2018-01-06 12:27



Credo che ci siano un numero di risposte errate a questo argomento. Contrariamente alla credenza comune, "indefinito" è non una parola chiave in JavaScript e può infatti avere un valore assegnato ad esso.

Codice corretto

Il modo più efficace per eseguire questo test è:

if (typeof myVar === "undefined")

Ciò restituirà sempre il risultato corretto e persino gestisce la situazione myVar non è dichiarato

Codice degenerato NON USARE.

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.


803
2017-08-23 18:03



In JavaScript c'è nullo e c'è non definito. Hanno significati diversi.

  • non definito significa che il valore variabile non è stato definito; non si sa quale sia il valore.
  • nullo significa che il valore della variabile è definito e impostato su null (non ha valore).

Marijn Haverbeke afferma, nel suo libro online gratuito "JavaScript eloquente"(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 null è per lo più accademica, e di solito non molto interessante. Nei programmi pratici, è spesso necessario verificare se qualcosa 'ha un valore'. In questi casi, può essere usata l'espressione qualcosa == undefined, perché, anche se non sono esattamente lo stesso valore, null == undefined produrrà true.

Quindi, immagino che il modo migliore per verificare se qualcosa non fosse definito sarebbe:

if (something == undefined)

Spero che questo ti aiuti!

Modificare: In risposta alla tua modifica, le proprietà dell'oggetto dovrebbero funzionare nello stesso modo.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

133
2017-08-26 07:36



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 del valore undefined e per se esiste una variabile. Nella stragrande maggioranza dei casi, sai quando esiste una variabile, e typeof introdurrà il potenziale per un errore silenzioso se si commette un errore di battitura nel nome della variabile o nel letterale stringa '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 non si stia eseguendo il rilevamento delle caratteristiche², dove c'è incertezza se un determinato nome sarà incluso nella portata (come il controllo typeof module !== 'undefined' come passaggio nel codice specifico per un ambiente CommonJS), typeof è una scelta dannosa se utilizzata su una variabile e l'opzione corretta è quella di confrontare direttamente il valore:

var foo = …;

if (foo === undefined) {
    ⋮
}

Alcuni equivoci comuni su questo includono:

  • che legge una variabile "non inizializzata" (var foo) o parametro (function bar(foo) { … }, chiamato come bar()) avrà esito negativo. Questo semplicemente non è vero - le variabili senza inizializzazione esplicita e i parametri che non sono stati dati i valori diventano sempre undefinede sono sempre in ambito.

  • quella 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, dal momento che ES5, questa proprietà è stata sola lettura e non configurabile. Nessun browser moderno permetterà il undefined proprietà da cambiare, e dal 2017 questo è il caso da molto tempo. La mancanza di modalità rigorosa non influisce undefinedAnche il comportamento - rende solo dichiarazioni come undefined = 5 non fare nulla invece di lanciare. Tuttavia, poiché non è una parola chiave, puoi farlo dichiarare variabili con il nome undefinede quelle variabili potrebbero essere cambiate, rendendo questo modello una volta comune:

    (function (undefined) {
        // …
    })()
    

    Di Più pericoloso che usare il globale undefined. Se devi essere compatibile ES3, sostituisci undefined 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 si disinteressano, è il momento di affrontare la vera domanda: le proprietà degli oggetti. Non c'è motivo di usare mai typeof per le proprietà dell'oggetto. La precedente eccezione riguardante il rilevamento delle funzioni non si applica qui - typeof ha solo un comportamento speciale sulle variabili e le espressioni che fanno riferimento alle proprietà dell'oggetto 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 motivo per cui si sta utilizzando typeof, perché ha più senso da usare === per controllare l'uguaglianza, perché potrebbe essere refactored per controllare il valore di una variabile più tardi, e perché sembra semplicemente migliore, dovresti sempre usare === undefined³ anche qui.

Qualcos'altro da considerare quando si tratta di proprietà dell'oggetto è se si vuole veramente controllare undefined affatto. Un nome di proprietà dato può essere assente su un oggetto (producendo il valore undefined quando letto), presente sull'oggetto stesso con il valore undefined, presente sul prototipo dell'oggetto con il valore undefinedo presente su uno di quelli con unundefined valore. 'key' in obj ti dirà se una chiave è ovunque sulla catena di prototipi di un oggetto, e Object.prototype.hasOwnProperty.call(obj, 'key') ti dirà se è direttamente sull'oggetto. Non andrò nei dettagli in questa risposta sui prototipi e sull'uso di oggetti come mappe a chiave stringa, però, perché è principalmente inteso a contrastare tutti i cattivi consigli in altre risposte, indipendentemente dalle possibili interpretazioni della domanda originale. Leggere su prototipi di oggetti su MDN per più!

¹ scelta insolita del nome della variabile di esempio? questo è il vero codice morto dall'estensione NoScript per Firefox.
² non dare per scontato che non sapendo che cosa è in ambito è ok in generale, però. vulnerabilità bonus causata dall'abuso dell'ambito dinamico: Progetto Zero 1225
³ assumendo di nuovo un ambiente ES5 + e quello undefined si riferisce a undefined proprietà dell'oggetto globale. sostituire void 0 altrimenti.


130
2018-02-26 21:17



Cosa significa questo: "proprietà dell'oggetto non definita"?

In realtà può significare due cose completamente diverse! In primo luogo, può significare la proprietà che non è mai stata definita nell'oggetto e, in secondo luogo, può significare il proprietà che ha un valore non definito. Diamo un'occhiata a questo codice:

var o = { a: undefined }

È o.a non definito? Sì! Il suo valore non è definito. È o.b non definito? Sicuro! Non esiste affatto la proprietà "b"! OK, vedi ora come si comportano i diversi approcci 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.

Quindi che si fa?

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 qualche proprietà e non importa del suo valore.

'prop' in obj

Gli appunti:

  • Non è possibile controllare un oggetto e le sue proprietà contemporaneamente. Ad esempio, questo x.a === undefined o questo typeof x.a == 'undefined' rilanci ReferenceError: x is not defined se x non è definito.
  • Variabile undefined è una variabile globale (quindi in realtà lo è window.undefined nei browser). È stato supportato dalla prima edizione di ECMAScript e poiché ECMAScript 5 lo è sola lettura. Quindi nei browser moderni non può essere ridefinito in vero come molti autori amano spaventarci, ma questo è ancora vero per i browser più vecchi.

Lotta finale: obj.prop === undefined vs typeof obj.prop == 'undefined'

Plus di obj.prop === undefined:

  • È un po 'più corto e sembra un po' più carino
  • Il motore JavaScript ti darà un errore se hai sbagliato l'ortografia undefined

Minuses di obj.prop === undefined:

  • undefined può essere sovrascritto nei vecchi browser

Plus di typeof obj.prop == 'undefined':

  • È davvero universale! Funziona con i browser nuovi e vecchi.

Minuses di typeof obj.prop == 'undefined':

  • 'undefned' (errori di ortografia) qui è solo una costante di stringa, quindi il motore JavaScript non può aiutarti se hai sbagliato ad ortografarlo come ho fatto io.

Aggiornamento (per JavaScript lato server):

Node.js supporta la variabile globale undefined come global.undefined (può anche essere usato senza il prefisso 'globale'). Non conosco altre implementazioni di JavaScript lato server.


100
2017-08-08 20:28



Il problema si riduce a tre casi:

  1. L'oggetto ha la proprietà e il suo valore non lo è undefined.
  2. L'oggetto ha la proprietà e il suo valore è undefined.
  3. L'oggetto non ha la proprietà.

Questo ci dice qualcosa che considero importante:

C'è una differenza tra un membro indefinito 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 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 per null anche le voci

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Direi che in alcuni casi ha più senso (ed è più chiaro) per verificare se la proprietà è lì, che controllare se è indefinito, e l'unico caso in cui questo controllo sarà diverso è il caso 2, il caso raro di una voce effettiva nell'oggetto con un valore non definito.

Ad esempio: ho appena effettuato 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 assegno per indefinito.

if( "x" in blob ) { fn(blob.x); }

Ma come è stato detto questi non sono esattamente gli stessi (ma sono più che sufficienti per le mie esigenze).


59
2018-06-08 04:04



if ( typeof( something ) == "undefined") 

Questo ha funzionato per me mentre gli altri no.


38
2017-07-27 16:03