Contenido

isDefined() en Javascript

4 feb

+ 8

Hace unos días, me encontré un post en Digg, que hablaba sobre la función isDefined() portada de ColdFusion a Javascript. En el mismo post de Jehiah Czebotar, se proponen alternativas y diferentes métodos de detectar de una variable está definida o no.

En el trabajo es algo que no me canso de repetir, y es que antes de usar un elemento, variable, función,… debemos comprobar que esta exista y así evitarnos problemas en nuestros scripts, y es que estos pequeños detalles marcan la diferencia.

Ejemplo erroneo

var obj = document.getElementByID("prueba");
alert(obj.href);

 En este ejemplo, pueden ocurrir 2 cosas, que el elemento “prueba” no exista y de error o que el elemento exista y en este caso nos veremos condicionados a que se trate de un enlace, link o otro elemento con el atributo href. En estos casos siempre hay que comprobar antes de usar.

Ejemplo corregido

var obj = document.getElementById("prueba");
if (obj) { // Evitamos que el elemento no exista
    alert((obj.href || "no existe")); //Evitamos que la propiedad no exista
}

De esta forma, armamos a más nuestro script con un par de comprobaciones que harán que sea más seguro usar nuestro elementos, variables, funciones. En este caso, vemos que hemos añadido una comprobación:

if (obj) { ...

Esta comprobación, nos permite asegurar que el objeto existe y que podemos usarlo a partir de este punto. Pero aún nos faltará una comprobación más para validar que el atributo que vamos a usar existe y está definido para nuestro objeto.

(obj.href || "no existe");

De esta forma, comprobamos que el atributo href existe, en caso negativo nos mostrará el texto “no existe”. El formato usado es una compresión del famoso operador ternario:

(obj.href)?obj.href:"no existe";

La función isDefined()

En muchos lenguajes de programación tenemos la posibilidad de conocer si una variable está definida antes de usarla, de esta forma podemos condicionar el funcionamiento de nuestros scripts. En Javascript tenemos unas cuantas posibilidades, he realizado un test para evaluar con es más rápida y los resultados has sido

El test

He realizado un test sobre cada una de las 4 funciones a las que les he aplicado 3 posibles iteraciones, 1.000, 10.000 y 100.000 respectivamente. En cada función y cada iteración he sacado tiempos en casos de variables encontradas y variables no encontradas, de esta forma podemos conocer los tiempos en ambos casos. He usado Windows XP + Firefox 2.0.0.11 + Firebug.

Las funciones

1)
function isDefined(variable) {
    return (typeof(window[variable]) == "undefined")?  false: true;
}

2)
function isDefined(variable, object) {
     return (typeof(eval(object)[variable]) == "undefined")? false: true;
}

3)
function isDefined(variable, object) {
     return (typeof(eval(object)[variable]) != 'undefined');
}

4)
function isDefined(variable) {
   return eval('(typeof('+variable+') != "undefined");');
}

Resultados

1000 10000 100000
Función SI NO SI NO SI NO
1 15ms 63ms 63ms 297ms 953ms 3625ms
2 547ms 750ms 3547ms 3593ms 34765ms 34781ms
3 219ms 234ms 3125ms 3562ms 34421ms 34968ms
4 219ms 235ms 3468ms 4141ms 31593ms 34531ms

Conclusiones

Los tiempos hablan por si solos, vemos como la función (1), atacando directamente al objeto window, que es el que contendrá todas las variables (globales), por ese motivo todas las demás funciones han sido realizadas sobre el mismo objeto. El uso de eval() ha penalizado considerablemente el resultado de las demás funciones lo que afianza más mi poco amor por esta función.

Función Ganadora

function isDefined(variable) {
    return (typeof(window[variable]) == "undefined")?  false: true;
}
//Versión reducida (Gracias DN)
function isDefined( variable) { return (typeof(window[variable]) != "undefined");}

//Uso:
isDefined("nombre_variable");

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.