2010-04-01 4 views
344

Stiamo spesso utilizzando il seguente codice di modello nel nostro codice JavaScriptCome verificare una variabile non definita o nulla in JavaScript?

if (typeof(some_variable) != 'undefined' && some_variable != null) 
{ 
    // Do something with some_variable 
} 

C'è un modo meno prolissa di controllo che ha lo stesso effetto?

Secondo alcuni forum e la letteratura che dice semplicemente quanto segue dovrebbe avere lo stesso effetto.

if (some_variable) 
{ 
    // Do something with some_variable 
} 

Purtroppo, Firebug valuta una tale dichiarazione come errore runtime quando some_variable è indefinito, mentre il primo è bene per essa. Questo è solo un comportamento (indesiderato) di Firebug o c'è davvero qualche differenza tra questi due modi?

+34

'if (some_variable) {...}' non sarà eseguito se 'some_variable' è' false' o '0' o ... – kennytm

+0

buon punto;) Ma diciamo che io so non può essere falso o 0 e voglio solo verificare se posso usarlo in qualche logica (come una stringa, array, ecc.) –

+0

Correlati: http://stackoverflow.com/questions/27509/detecting-an -undefined-object-property-in-javascript –

risposta

257

si deve distinguere tra due casi

1) Non definita variabili, come 'foo'. Riceverai un errore se accedi a una variabile non definita in un contesto diverso da typeof.

if(typeof someUndefVar == whatever) -- works 
    if(someUndefVar) -- error 

Quindi, per le variabili, il tipo di controllo è obbligatorio. D'altra parte, è solo raramente necessario - di solito lo conosce se le tue variabili sono definite o meno.

2) Non definito proprietà, come someExistingObj.someUndefProperty. Una proprietà non definita non produce un errore e restituisce semplicemente "indefinito", che, una volta convertito in booleano, restituisce un valore falso. Quindi, se non ti interessa di '0' e 'falso', if(obj.undefProp) è ok. C'è un linguaggio comune basato su questo fatto:

value = obj.prop || defaultValue 

che significa "se obj ha un puntello, l'uso che, altrimenti di default".

Alcune persone considerano questo comportamento confusione, sostenendo che porta a difficili da trovare gli errori e consiglia di utilizzare in operator invece

value = ('prop' in obj) ? obj.prop : defaultValue 
+1

Quindi potresti parlare di hasOwnProperty e prototipi. 'indexOf' in []! == [].hasOwnProperty ('indexOf') – Alsciende

+1

Sì, ho pensato di aggiungere questo, ma ho deciso di sacrificare la completezza per brevità. ;) – user187291

+2

c'è qualcosa di sbagliato nell'usare semplicemente 'if (!! some_variable) {...}' ??? –

15

Se si tenta di fare riferimento a una variabile non dichiarata, verrà generato un errore in tutte le implementazioni di JavaScript.

Le proprietà degli oggetti non sono soggette alle stesse condizioni. Se una proprietà dell'oggetto non è stata definita, non verrà generato un errore se si tenta di accedervi. Quindi, in questa situazione si potrebbe accorciare:

if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null) 

a

if (myObj.some_property != null) 

Con questo in mente, e il fatto che le variabili globali sono accessibili come proprietà dell'oggetto globale (window nel caso di un browser), è possibile utilizzare il seguente per le variabili globali:

if (window.some_variable != null) { 
    // Do something with some_variable 
} 

negli ambiti locali, è sempre utile per rendere le variabili sicuri vengono dichiarate nella parte superiore del vostro codice blocco, questo salverà sugli usi ricorrenti di typeof.

+11

Perderai NaN, 0, "" e false perché non sono nulli né indefiniti ma falsi. –

+0

@Andreas Köberle ha ragione. Anche l'operatore di uguaglianza non rigorosa dice che null è diverso da NaN, 0, "" e false. Dovresti fare "if (myObj.some_property! = Null)" per ottenere un comportamento equivalente. – thejoshwolfe

265

Penso che il modo più efficace per verificare "il valore è null o undefined" è

if (some_variable == null){ 
    // some_variable is either null or undefined 
} 

Così queste due linee sono equivalenti:

if (typeof(some_variable) !== "undefined" && some_variable !== null) {} 
if (some_variable != null) {} 

Nota 1

Come indicato nella domanda, la breve variante richiede che some_variable è stata dichiarata, altrimenti un ReferenceError saranno gettati. Tuttavia, in molti casi d'uso si può supporre che questo è sicuro:

controllo per gli argomenti opzionali:

function(foo){ 
    if(foo == null) {...} 

di controllo per le proprietà su un oggetto esistente

if(my_obj.foo == null) {...} 

D'altra parte typeof può trattare con variabili globali non dichiarate (restituisce semplicemente undefined). Tuttavia questi casi dovrebbero essere ridotti al minimo per buone ragioni, come spiegato da Alsciende.

Nota 2

Questo - ancora più breve - variante è non equivalente:

if (!some_variable) { 
    // some_variable is either null, undefined, 0, NaN, false, or an empty string 
} 

così

if (some_variable) { 
    // we don't get here if some_variable is null, undefined, 0, NaN, false, or "" 
} 

Nota 3

In generale si consiglia di utilizzare === anziché ==. La soluzione proposta è un'eccezione a questa regola. Il JSHint syntax checker fornisce anche l'opzione eqnull per questo motivo.

Dal jQuery style guide:

Strict equality checks (===) should be used in favor of ==. The only exception is when checking for undefined and null by way of null.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null; 
+1

Differenza molto importante (che era già menzionata nella domanda btw). Ecco perché tutti usano typeof. Scusate ma non capisco dove la vostra risposta sia utile, basta indicare ciò che è stato detto nella domanda e nelle prime righe si dice che è anche sbagliato. – TMS

+20

Mi spiace, ma non sono d'accordo ;-) L'uso di '== null' è il più efficiente da testare per 'null o undefined' (che è l'argomento delle domande). Non è affatto raro (usato 43 volte in jQuery 1.9.1), poiché molto spesso si sa che la variabile è stata dichiarata o si prova per una proprietà di un oggetto esistente come 'if (o.foo == null) '. – mar10

+1

@ mar10 (aUndefinedVar == null) fornisce un errore "aUndefinedVar non definito" non vero. – Rannnn

4

Poiché non esiste una sola risposta completa e corretta, cercherò di riassumere:

In generale, l'espressione:

if (typeof(variable) != "undefined" && variable != null) 

non può essere semplificato, perché il variable potrebbe non essere dichiarato, quindi omettere lo typeof(variable) != "undefined" risulterebbe in ReferenceError.Ma, è possibile semplificare l'espressione a seconda del contesto:

Se il variable è globale, è possibile semplificare a:

if (window.variable != null) 

Se è locali, probabilmente si può evitare situazioni quando questa variabile è sommerso, e anche semplificare a:

if (variable != null) 

Se è proprietà dell'oggetto, non devi preoccuparti di ReferenceError:

if (obj.property != null) 
+0

È 'navigator' parte di' window'? Quando otteniamo un'eccezione per 'navigator non è definito', possiamo usare il test' window.navigator! = Null'? – jww

-1

è necessario definire una funzione di questo modulo:

validate = function(some_variable){ 
    return(typeof(some_variable) != 'undefined' && some_variable != null) 
} 
+0

Questo genererà lo stesso ReferenceError se la variabile non è dichiarata. – Chad

9

primo luogo è necessario essere molto chiari su ciò che si prova. JavaScript ha tutti i tipi di conversioni implicite per farti saltare in aria e due diversi tipi di comparatori di uguaglianza: == e ===.

Una funzione, test(val) che i test per null o undefined dovrebbe avere le seguenti caratteristiche:

test(null)   => true 
test(undefined) => true 
test(0)   => false 
test(1)   => false 
test(true)   => false 
test(false)  => false 
test('s')   => false 
test([])   => false 

Vediamo quale delle idee qui in realtà superare la nostra prova.

Questi lavori:

val == null 
val === null || val === undefined 
typeof(val) == 'undefined' || val == null 
typeof(val) === 'undefined' || val === null 

Questi non funzionano:

typeof(val) === 'undefined' 
!!val 

ho creato un jsperf entry to compare the correctness and performance di questi approcci. I risultati non sono conclusivi per il momento in quanto non ci sono state corse sufficienti su diversi browser/piattaforme. Si prega di prendere un minuto per eseguire il test sul tuo computer!

Allo stato attuale, sembra che il semplice test val == null dia le migliori prestazioni. È anche il più corto. Il test può essere negato a val != null se si desidera il complemento.

3

Come menzionato in una delle risposte, si può essere fortunati se si parla di una variabile che ha una portata globale. Come forse saprai, le variabili che definisci globalmente tendono ad essere aggiunte all'oggetto Windows. È possibile usufruire di questo fatto in modo diciamo che si accede a un bleh variabile chiamata, basta usare l'operatore doppia invertito (!!)

!!window['bleh']; 

Questo sarebbe restituire un falso mentre bleh non è stato dichiarato e assegnato un valore di .

0

Il test di nullità (if (value == null)) o non nullità (if (value != null)) è meno dettagliato rispetto al test dello stato di definizione di una variabile.

Inoltre, il test if (value) (o if(obj.property)) per garantire l'esistenza della variabile (o un oggetto di proprietà) non riesce se è definito con un valore booleano false.Caveat emptor :)

19

Il controllo nullo con uguaglianza normale restituirà anche true per indefinito.

if (window.variable == null) alert('variable is null or undefined');

JS Equality

+0

NaN diverso da Nan? –

+0

@monotheist NaN non è uguale a NaN (vedere [pagina NaN di MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)). Javascript utilizza IEEE-754 per il loro punto mobile che specifica questo comportamento. Ci sono alcuni pensieri a questo proposito, vedi http://stackoverflow.com/a/23666623/2563765 – Steven

0

Entrambi i valori possono essere facilmente distinte utilizzando l'rigorosa operatore di confronto: ad esempio

Lavorare in:

http://www.thesstech.com/tryme?filename=nullandundefined

codice di esempio:

function compare(){ 
    var a = null; //variable assigned null value 
    var b; // undefined 
    if (a === b){ 
     document.write("a and b have same datatype."); 
    } 
    else{ 
     document.write("a and b have different datatype."); 
    } 
} 
21

In standard più recenti come JavaScript ES5 e ES6 si può solo dire

> Boolean(0) //false 
> Boolean(null) //false 
> Boolean(undefined) //false 

tutto return false, che è simile al controllo di Python di variabili vuote. Quindi, se si vuole scrivere la logica condizionale intorno una variabile, basta dire

if (Boolean(myvar)){ 
    // Do something 
} 

qui "null" o "stringa vuota" o "indefinito" sarà gestito in modo efficiente.

+2

supportato fino a mi piace ie5, perché questo non è più noto !? – Himmators

+0

OP desiderava solo test diversi da 'null' e' undefined', altri valori falsy dovrebbero restituire true! –

4

È possibile controllare se la variabile ha un valore o meno. Significato,

if(myVariable) { 
//mayVariable is not : 
//null 
//undefined 
//NaN 
//empty string ("") 
//0 
//false 

} 

Se non si sa se esiste una variabile (che significa, se è stato dichiarato) si dovrebbe verificare con l'operatore typeof. per esempio.

if(typeof myVariable !== 'undefined') { 
    // myVariable will get resolved and it is defined 
} 
2

qualunque yyy è undefined o null, esso ritornerà vero

if (typeof yyy == 'undefined' || !yyy) { 
    console.log('yes'); 
} else { 
    console.log('no'); 
} 

if (!(typeof yyy == 'undefined' || !yyy)) { 
    console.log('yes'); 
} else { 
    console.log('no'); 
} 

senza

0

Aprire le Strumenti per sviluppatori nel browser e basta provare il codice mostrato nell'immagine qui sotto.

Img1 Img2