2010-04-01 15 views
344

Estamos con frecuencia usando el siguiente patrón de código en nuestro código JavaScript¿Cómo verificar una variable indefinida o nula en JavaScript?

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

¿Hay una manera menos detallado de verificación que tiene el mismo efecto?

Según algunos foros y la literatura diciendo simplemente lo siguiente debería tener el mismo efecto.

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

Desafortunadamente, Firebug evalúa una declaración como error en tiempo de ejecución cuando some_variable es indefinido, mientras que el primero está muy bien para él. ¿Es esto solo un comportamiento (no deseado) de Firebug o hay realmente alguna diferencia entre esas dos formas?

+34

'si (some_variable) {...}' no se ejecuta si es '' some_variable' false' o '0' o ... – kennytm

+0

buen punto;) Pero digamos que sé no puede ser falso o 0 y solo quiero verificar si puedo usarlo en alguna lógica (como una cadena, matriz, etc.) –

+0

Relacionado: http://stackoverflow.com/questions/27509/detecting-an -un-definido-objeto-propiedad-en-javascript –

Respuesta

257

hay que diferenciar entre dos casos

1) Undefined las variables, como 'foo'. Obtendrá un error si accede a una variable indefinida en cualquier contexto que no sea typeof.

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

Por lo tanto, para las variables, el tipo de verificación es imprescindible. Por otro lado, solo se necesita raramente: generalmente sabe si sus variables están definidas o no.

2) Undefined propiedades, como someExistingObj.someUndefProperty. Una propiedad indefinida no produce un error y simplemente devuelve "indefinido", que, cuando se convierte en booleano, se evalúa como falso. Entonces, si no te importan los '0' y 'falso', if(obj.undefProp) está bien. Hay un lenguaje común basado en este hecho:

value = obj.prop || defaultValue 

que significa "si obj tiene un apoyo, el uso que, de otro modo por defecto".

Algunas personas consideran que este comportamiento confuso, argumentando que conduce a difíciles de encontrar errores y recomendar el uso de in operator lugar

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

Luego, podría hablar sobre hasOwnProperty y prototipos. 'indexOf' en []! == [].hasOwnProperty ('indexOf') – Alsciende

+1

Sí, pensé en agregar esto, pero decidí sacrificar la integridad para abreviar. ;) – user187291

+2

¿Hay algo mal con solo usar 'if (!! some_variable) {...}' ??? –

15

Si intenta hacer referencia a una variable no declarada, se generará un error en todas las implementaciones de JavaScript.

Las propiedades de los objetos no están sujetas a las mismas condiciones. Si no se ha definido una propiedad de objeto, no se lanzará un error si intenta acceder a ella. Así que en esta situación se podría acortar:

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

a

if (myObj.some_property != null) 

Con esto en mente, y el hecho de que las variables globales son accesibles como propiedades del objeto global (window en el caso de un navegador), puede utilizar el siguiente para las variables globales:

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

en los ámbitos locales, que siempre son útiles para hacer las variables estén declaradas en la parte superior de su código bloque, esto ahorrará en usos recurrentes de typeof.

+11

Extrañarás NaN, 0, "" y falsa causa de que no son nulos ni indefinidos, sino también falsos. –

+0

@Andreas Köberle tiene razón. Incluso el operador de igualdad no estricta dice que null es diferente de NaN, 0, "" y falso. Tendría que hacer 'if (myObj.some_property! = Null)' para obtener un comportamiento equivalente. – thejoshwolfe

265

Creo que la forma más eficiente para la prueba de "valor es null o undefined" es

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

Así pues, estas dos líneas son equivalentes:

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

Nota 1

Como se menciona en la pregunta, la variante corta requiere que some_variable ha sido declarado, de lo contrario será lanzado un ReferenceError. Sin embargo, en muchos casos de uso se puede asumir que esto es seguro:

cheque por argumentos opcionales:

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

verificación de las propiedades de un objeto existente

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

Por otro lado typeof puede tratar con variables globales no declaradas (simplemente devuelve undefined). Sin embargo, estos casos deberían reducirse al mínimo por buenas razones, como explicó Alsciende.

Nota 2

Esta - incluso más corto - variante es no equivalente:

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

así

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

Nota 3

En general, se recomienda utilizar === en lugar de ==. La solución propuesta es una excepción a esta regla. El JSHint syntax checker incluso proporciona la opción eqnull por este motivo.

Desde el 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

Diferencia muy importante (que ya se mencionó en la pregunta por cierto). Es por eso que todos usan typeof. Lo siento pero no entiendo dónde es útil su respuesta, solo dice lo que se dijo en la pregunta y en las primeras líneas lo dice incluso equivocado. – TMS

+20

Lo siento, pero tengo que estar en desacuerdo ;-) Usar '== null' es en realidad el más eficiente para probar 'nulo o indefinido' (que es el tema de las preguntas). No es poco común (se usa 43 veces en jQuery 1.9.1), ya que muy a menudo usted sabe que la variable fue declarada, o prueba una propiedad de un objeto existente como 'if (o.foo == null) '. – mar10

+1

@ mar10 (aUndefinedVar == null) le da un error "aUndefinedVar is not defined" no es cierto. – Rannnn

4

Dado que no hay una única respuesta completa y correcta, voy a tratar de resumir:

En general, la expresión:

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

no puede haber simplificado, porque variable podría no declararse, por lo que omitir typeof(variable) != "undefined" daría lugar a ReferenceError.Pero, puede simplificar la expresión de acuerdo con el contexto:

Si el variable es mundial, se puede simplificar a:

if (window.variable != null) 

Si es locales, es probable que pueda evitar situaciones cuando esta variable no está declarada, y también se simplifica a:

if (variable != null) 

Si es propiedad de objeto, usted no tiene que preocuparse de ReferenceError:

if (obj.property != null) 
+0

¿Forma parte el 'navigator' de' window'? Cuando obtenemos una excepción para 'navigator is not defined', ¿podemos usar la prueba' window.navigator! = Null'? – jww

-1

debe definir una función de esta forma:

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

Eso generará el mismo error de referencia si la variable no está declarada. – Chad

9

primer lugar usted tiene que ser muy claro acerca de lo que se prueba. JavaScript tiene todo tipo de conversiones implícitas para hacerte tropezar, y dos tipos diferentes de comparador de igualdad: == y ===.

Una función, test(val) que las pruebas para null o undefined debe tener las siguientes características:

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

Vamos a ver cuál de las ideas aquí en realidad pasar nuestra prueba.

Estos trabajos:

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

estos no funcionan:

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

he creado un jsperf entry to compare the correctness and performance de estos enfoques. Los resultados no son concluyentes por el momento, ya que no se han realizado suficientes ejecuciones en diferentes navegadores/plataformas. ¡Dedique un minuto a realizar la prueba en su computadora!

En la actualidad, parece que la prueba simple val == null da el mejor rendimiento. También es más o menos el más corto. La prueba puede negarse a val != null si desea el complemento.

3

Como se menciona en una de las respuestas, puede estar de suerte si se trata de una variable que tiene un alcance global. Como ya sabrá, las variables que define globalmente tienden a agregarse al objeto de Windows. Usted puede tomar ventaja de este hecho lo que permite decir que está accediendo a una variable llamada bleh, sólo tiene que utilizar el operador doble invertida (!!)

!!window['bleh']; 

Esto volvería una falsa mientras bleh no se ha declarado y se asigna un valor .

0

La nulidad de prueba (if (value == null)) o no-nulidad (if (value != null)) es menos detallada que probar el estado de definición de una variable.

Además, prueba if (value) (o if(obj.property)) para asegurar que la existencia de su variable (o propiedad del objeto) falla si se define con un valor booleano false.Caveat Emptor :)

19

La comprobación de null con igualdad normal también será verdadera para indefinido.

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

JS Equality

+0

NaN no es igual a Nan? –

+0

@monotheist NaN no es igual a NaN (ver [página de NaN de MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)). Javascript usa IEEE-754 para su punto flotante que especifica este comportamiento. Hay algunas ideas para esto, vea http://stackoverflow.com/a/23666623/2563765 – Steven

0

Ambos valores pueden distinguirse fácilmente mediante el uso de la estricta operador de comparación: ejemplo

Trabajar en:

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

Código de ejemplo:

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

En los nuevos estándares de JavaScript como ES5 y ES6 se puede decir simplemente

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

todo return false, que es similar a la verificación de las variables vacías de Python. lo tanto, si desea escribir la lógica condicional en torno a una variable, simplemente decir

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

aquí "nulo" o "cadena vacía" o "indefinido" serán manejados de manera eficiente.

+2

compatible hasta como ie5, ¿por qué no es más conocido? – Himmators

+0

OP solo quería probar diferente de 'null' y' undefined', ¡otros valores de faly deberían ser verdaderos! –

4

Puede verificar si la variable tiene un valor o no. Es decir,

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

} 

Si usted no sabe si existe una variable (es decir, si se ha declarado) usted debe consultar con el operador typeof. p.ej.

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

lo yyy es indefinido o nula, devolverá verdadero

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

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

sin

0

Abiertas las Herramientas para desarrolladores en su navegador y solo prueba el código que se muestra en la imagen de abajo.

Img1 Img2

Cuestiones relacionadas