vacio - validar variable no definida javascript
¿Cómo verificar "indefinido" en JavaScript? (16)
Actualización 2018-07-25
Han pasado casi cinco años desde que se hizo esta publicación por primera vez, y JavaScript ha recorrido un largo camino. Al repetir las pruebas en la publicación original, no encontré una diferencia consistente entre los siguientes métodos de prueba:
-
abc === undefined
-
abc === void 0
-
typeof abc == ''undefined''
-
typeof abc === ''undefined''
Incluso cuando modifiqué las pruebas para evitar que Chrome las optimice, las diferencias fueron insignificantes. Como tal, ahora recomendaría abc === undefined
para mayor claridad.
Contenido relevante de chrome://version
:
- Google Chrome: 67.0.3396.99 (compilación oficial) (64 bits) (cohorte: estable)
- Revisión: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs / branch-heads / 3396 @ {# 790}
- OS: Windows
- JavaScript: V8 6.7.288.46
- Agente de usuario: Mozilla / 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit / 537.36 (KHTML, como Gecko) Chrome / 67.0.3396.99 Safari / 537.36
Original post 2013-11-01
En Google Chrome, lo siguiente fue un poco más rápido que una prueba de tipo:
if (abc === void 0) {
// Undefined
}
La diferencia fue despreciable. Sin embargo, este código es más conciso y más claro a simple vista para alguien que sabe lo que significa void 0
. Tenga en cuenta, sin embargo, que abc
todavía debe ser declarado.
Tanto typeof
como void
fueron significativamente más rápidos que comparando directamente con undefined
. Utilicé el siguiente formato de prueba en la consola de desarrollador de Chrome:
var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
if (TEST) {
void 1;
}
}
end = +new Date();
end - start;
Los resultados fueron los siguientes:
Test: | abc === undefined abc === void 0 typeof abc == ''undefined''
------+---------------------------------------------------------------------
x10M | 13678 ms 9854 ms 9888 ms
x1 | 1367.8 ns 985.4 ns 988.8 ns
Tenga en cuenta que la primera fila está en mili segundos, mientras que la segunda fila está en nano segundos. Una diferencia de 3,4 nanosegundos no es nada. Los tiempos fueron bastante consistentes en las pruebas posteriores.
Esta pregunta ya tiene una respuesta aquí:
- Detectando una propiedad de objeto indefinida 41 respuestas
- Cómo verificar una variable no definida en JavaScript 13 respuestas
- Cómo manejar ''indefinido'' en javascript [duplicar] 3 respuestas
- ¿Cómo comprobar si existe una variable en javascript? 8 respuestas
¿Cuál es la forma más adecuada de probar si una variable no está definida en JavaScript? He visto varias formas posibles:
if (window.myVariable)
O
if (typeof(myVariable) != "undefined")
O
if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?
Al contrario de la respuesta de @Thomas Eding:
Si olvido declarar myVar
en mi código, entonces obtendré que myVar is not defined
.
Tomemos un ejemplo real:
Tengo un nombre de variable, pero no estoy seguro de si está declarado en algún lugar o no.
Entonces la respuesta de @ Anurag ayudará:
var myVariableToCheck = ''myVar'';
if (window[myVariableToCheck] === undefined)
console.log("Not declared or declared, but undefined.");
// Or you can check it directly
if (window[''myVar''] === undefined)
console.log("Not declared or declared, but undefined.");
Algunos escenarios que ilustran los resultados de las distintas respuestas: http://jsfiddle.net/drzaus/UVjM4/
(Tenga en cuenta que el uso de var
para in
pruebas hace una diferencia cuando se encuentra en una envoltura con alcance)
Código de referencia:
(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;
}
})();
Y resultados:
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
Como ninguna de las otras respuestas me ayudó, sugiero hacer esto. Me funcionó en Internet Explorer 8:
if (typeof variable_name.value === ''undefined'') {
// variable_name is undefined
}
En este artículo leí que los marcos como Underscore.js usan esta función:
function isUndefined(obj){
return obj === void 0;
}
La forma más confiable que conozco de verificar que undefined
esté undefined
es usar void 0
.
Esto es compatible con navegadores más nuevos y más antiguos, por igual, y no se puede sobrescribir como window.undefined
en algunos casos.
if( myVar === void 0){
//yup it''s undefined
}
Lo uso como un parámetro de función y lo excluyo en la ejecución de la función de esa manera obtengo lo "real" indefinido. Aunque sí requiere que pongas tu código dentro de una función. Encontré esto mientras leía la fuente de jQuery.
undefined = 2;
(function (undefined) {
console.log(undefined); // prints out undefined
// and for comparison:
if (undeclaredvar === undefined) console.log("it works!")
})()
Por supuesto que puedes usar typeof
. Pero de todas formas, todo mi código está dentro de una función contenedora, por lo que el uso de este método probablemente me ahorra algunos bytes aquí y allá.
Necesitas usar typeof
.
if (typeof something != "undefined") {
// ...
}
Personalmente, siempre uso lo siguiente:
var x;
if( x === undefined) {
//Do something here
}
else {
//Do something else here
}
La propiedad window.undefined no se puede escribir en todos los navegadores modernos (JavaScript 1.8.5 o posterior). De la documentación de Mozilla: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined , veo esto: una razón para usar typeof () es que no arroja un error si La variable no ha sido definida.
Prefiero tener el enfoque de usar
x === undefined
porque falla y explota en mi cara en lugar de pasar / fallar en silencio si x no se ha declarado antes. Esto me alerta de que x no está declarada. Creo que todas las variables usadas en JavaScript deben ser declaradas.
Si está interesado en saber si una variable ha sido declarada independientemente de su valor, entonces usar el operador in
es la forma más segura de hacerlo. Considera este ejemplo.
// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"
Pero puede que este no sea el resultado previsto para algunos casos, ya que la variable o propiedad se declaró pero no se inicializó. Utilice el operador in
para una comprobación más robusta.
"theFu" in window; // true
"theFoo" in window; // false
Si está interesado en saber si la variable no se ha declarado o tiene el valor undefined
, use el operador typeof
.
if (typeof myVar != ''undefined'')
El operador typeof
está garantizado para devolver una cadena. Las comparaciones directas con undefined
son problemáticas, ya que undefined
puede sobrescribirse.
window.undefined = "omg";
"omg" == undefined // true
Como lo señaló @CMS, esto ha sido parchado en ECMAScript 5th ed., Y undefined
no se puede escribir.
if (window.myVar)
también incluirá estos valores falsos, por lo que no es muy robusto:
false 0 "" NaN null undefined
Gracias a @CMS por señalar que su tercer caso, if (myVariable)
también puede generar un error en dos casos. La primera es cuando no se ha definido la variable que lanza un ReferenceError
.
// abc was never declared.
if (abc) {
// ReferenceError: abc is not defined
}
El otro caso es cuando la variable ha sido definida, pero tiene una función getter que lanza un error cuando se invoca. Por ejemplo,
// or it''s a property that can throw an error
Object.defineProperty(window, "myVariable", {
get: function() { throw new Error("W00t?"); },
set: undefined
});
if (myVariable) {
// Error: W00t?
}
Si no está definido, no será igual a una cadena que contenga los caracteres "indefinido", ya que la cadena no está indefinida.
Puedes comprobar el tipo de la variable:
if (typeof(something) != "undefined") ...
A veces ni siquiera tienes que comprobar el tipo. Si el valor de la variable no se puede evaluar como falso cuando se establece (por ejemplo, si es una función), entonces puede evaluar la variable. Ejemplo:
if (something) {
something(param);
}
Usar typeof
es mi preferencia. Funcionará cuando la variable nunca haya sido declarada, a diferencia de cualquier comparación con los operadores ==
o ===
o el tipo de coerción usando if
. ( undefined
, a diferencia de null
, también se puede redefinir en entornos ECMAScript 3, lo que hace que no sea confiable para la comparación, aunque casi todos los entornos comunes ahora son compatibles con ECMAScript 5 o superior).
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
Yo personalmente uso
myVar === undefined
Advertencia: tenga en cuenta que ===
se usa sobre ==
y que myVar
se ha declarado previamente (no definido ).
No me gusta typeof myVar === "undefined"
. Creo que es larga e innecesaria. (Puedo hacer lo mismo en menos código).
Ahora algunas personas se arrodillarán de dolor cuando lean esto, gritando: "¡Espera! ¡WAAITTT! ¡Indefinido puede ser redefinido!"
Guay. Yo se esto. Por otra parte, la mayoría de las variables en Javascript pueden ser redefinidas. ¿Nunca debe usar un identificador incorporado que pueda ser redefinido?
Si sigues esta regla, bien por ti: no eres un hipócrita.
La cuestión es que, para realizar un montón de trabajo real en JS, los desarrolladores necesitan confiar en identificadores redefinibles para ser lo que son. No escucho a nadie que me diga que no debería usar setTimeout
porque alguien puede
window.setTimeout = function () {
alert("Got you now!");
};
En pocas palabras, el argumento "se puede redefinir" para no usar un raw === undefined
es falso.
(Si aún tiene miedo de que se redefina lo undefined
, ¿por qué está integrando ciegamente el código de biblioteca no probado en su base de código? O incluso más simple: una herramienta de creación de líneas).
Además, al igual que con el enfoque typeof
, esta técnica puede "detectar" variables no declaradas:
if (window.someVar === undefined) {
doSomething();
}
Pero ambas técnicas se filtran en su abstracción. Les insto a no usar esto o incluso
if (typeof myVar !== "undefined") {
doSomething();
}
Considerar:
var iAmUndefined;
Para detectar si se declara o no esa variable, es posible que deba recurrir al operador in
. (En muchos casos, simplemente puede leer el código O_o).
if ("myVar" in window) {
doSomething();
}
¡Pero espera! ¡Hay más! ¿Qué pasa si algún prototipo de magia de cadena está sucediendo ...? Ahora incluso el superior in
operador no es suficiente. (De acuerdo, he terminado aquí con respecto a esta parte, excepto para decir que, durante el 99% del tiempo, === undefined
(y **** tos **** typeof
) funciona bien. Si realmente te importa, puedes lea sobre este tema por sí mismo.)
var x;
if (x === undefined) {
alert ("I am declared, but not defined.")
};
if (typeof y === "undefined") {
alert ("I am not even declared.")
};
/* One more thing to understand: typeof ===''undefined'' also checks
for if a variable is declared, but no value is assigned. In other
words, the variable is declared, but not defined. */
// Will repeat above logic of x for typeof === ''undefined''
if (x === undefined) {
alert ("I am declared, but not defined.")
};
/* So typeof === ''undefined'' works for both, but x === undefined
only works for a variable which is at least declared. */
/* Say if I try using typeof === undefined (not in quotes) for
a variable which is not even declared, we will get run a
time error. */
if (z === undefined) {
alert ("I am neither declared nor defined.")
};
// I got this error for z ReferenceError: z is not defined
// x has not been defined before
if (typeof x === ''undefined'') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
if (typeof foo == ''undefined'') {
// Do something
};
Tenga en cuenta que la comparación estricta ( !==
) no es necesaria en este caso, ya que typeof
siempre devolverá una cadena.