PDA

Ver la Versión Completa : Saber si existe una variable


roman
04-06-2005, 00:31:48
Esto me da vergüenza preguntarlo pero llevo toda la mañana buscando y no he encontrado nada.

¿Cómo puedo saber en JavaScript si una variable existe o no? Algo así como el equivalente a isset de PHP.

// Gracias

roman
04-06-2005, 02:31:31
Bah! Parece que esto no es posible en javascript, lo cual es sorprendente en un lenguaje interpretado. La única forma que funciona es con sentencias try-catch:


try
{
alert(foo);
}
catch (error)
{
alert('La variable foo no está definida');
}


Aunque no me convence mucho usar excepciones para esto.

Afortunadamente, más que para una variable suelta yo lo quería para propiedades de objetos (pensé que sería lo mismo) y en ese caso sí se puede:



if (!objeto.getAttribute('foo'))
{
alert('La propiedad foo no está definida');
}


Si a alguien le da curiosidad saber para qué quería esto les cuento la historia y quizá a alguien le sirva.

Como me harta estar escribiendo funciones para validar formularios hice resumen de lo que generalmente necesito al momento de validar un control:

1. Checar que se haya llenado el dato
2. Checar que tenga la longitud adecuada
3. Checar que tenga el formato correcto

En cada caso, si algo está mal hago algo similar a esto:



alert('Formato incorrecto (correo electrónico)');
control.focus();


donde control es el control que se está validando.

Para la validación tengo que checar que

1. control.value no sea una cadena vacía
2. ereg.exec(control.value) no sea false
3. control.value.length coincida con la longitud esperada

Aquí ereg es una expresión regular para checar el formato, por ejemplo:

/[0-9]{4}-[0-9]{2}-[0-9]{2}/

checa que una fecha tenga el formato aaaa-mm-dd (más o menos).

Entonces, lo único que se requiere son cuatro cosas:

1. Mensaje a mostrar en caso de error
2. Saber si el dato es requerido o no
3. Expresión regular para checar el formato
4. Longitud esperada

En JavaScript podemos asignar propiedades nuevas a objetos:



fecha.required = true;
fecha.caption = 'Fecha de nacimiento';
fecha.ereg = /[0-9]{4}-[0-9]{2}-[0-9]{2}/


Estas asignaciones las podemos hacer en el evento onLoad de la página HTML.

Para, por ejemplo, checar el formato usaríamos esta función:



function check_format(control)
{
// si el atributo no existe es que no se requiere checar formato
if (!control.getAttribute('ereg'))
return true;

if (!control.ereg.exec(control.value))
{
alert('Dato con formato incorrecto: ' + control.caption);
control.focus();

return false;
}

return true;
}


Similarmente tendríamos funciones check_empty() y check_length() para verificar si el control está vacío o no. check_empty() primero verificaría la existencia del atributo 'required'. Si no existe o es false supone que no se requiere el dato y regresa true.

Como todas las funciones necesitan de la propiedad 'caption' para mostrar el mensaje de error, agrupo todas las verifiicaciones en esta función:



function check_control(control)
{
if (!control.getAttribute('caption'))
control.caption = control.name;

ok =
check_empty(control) &&
check_length(control) &&
check_format(control);

return ok;
}


Así, únicamente tengo que iterar la función check_control() sobre todos los controles del formulario:



function check_form(formulario)
{
var ok = true;

for (i = 0; i < formulario.elements.length; i++)
{
ok = check_control(formulario.elements[i]);
if (!ok) break;
}

return ok;
}


Y así, el evento onSubmit() del formulario se reduce a:



function form_submit(formulario)
{
return check_form(formulario);
}


Claro que esto sólo sirve para validaciones sencillas aunque yo normalmente es lo que necesito ya que las validaciones complejas se hacen del lado del servidor.

// Saludos

JavierB
04-06-2005, 19:11:58
Hola roman

Para saber si una variable JavaScript existe, peudes usar esto:

if(typeof foo=='undefined')
alert('no definida');
Saludos, :cool:

roman
04-06-2005, 22:56:36
Gracias JavierB. Lo he probadoy funciona bien. También me he dado cuenta que funciona así:


if (foo == null)
alert('no definida');


y ambas maneras funcionan también para propiedades de un objeto.

// Saludos

JavierB
05-06-2005, 11:19:49
Hola de nuevo.

Con tu código me da error: 'foo' no está definido :confused:

Saludos, :cool:

roman
07-06-2005, 17:10:57
Gracias Javier.

En efecto marca ese error. Yo creo que de tantas pruebas que hice me confundí o no sé. Me quedo con el typeof.

// Saludos

marto
12-06-2005, 01:53:12
Yo utilizo algo similar para validar mis formularios web. Me he hecho una API bastante completa, un dia de estos la subo, lo que pasa es que aun no esta "presentable".
Yo añado alguna cosa mas, como por ejemplo poner en los inputs un atributo de tipo "_tipo" en la que marco tipos con validaciones y mensajes genéricos, integer, float, currency, etc.


Claro que esto sólo sirve para validaciones sencillas aunque yo normalmente es lo que necesito ya que las validaciones complejas se hacen del lado del servidor.


para solucionar este problema, yo trabajo con otro atributo especial _onValidate, que retorna true si va bien y false si va mal. Entonces tu función check_control, quedaria así:


function check_control(control)
{
if (!control.getAttribute('caption'))
control.caption = control.name;

ok =
check_empty(control) &&
check_length(control) &&
check_format(control) &&
(
(!control.getAttribute("_onValidate") ||
(control._onValidate())
);

return ok;
}

roman
12-06-2005, 02:11:05
Hola marto,

De hecho he visto algo de lo que has hecho y me pareció muy interesante aunque es raro que yo haga validaciones en función del tipo de datos; por ello es que me enfoqué más en

check_empty,
check_format,
check_length

y curiosamente acabo de agregar hace unos días el check_custom para validaciones personalizadas.

Además de eso uso propiedades como

displayName - nombre a usar en mensajes de error (por defecto el nombre del control)

hint - cadena que se escribe automáticamente en el control cuando está vacío y estamos fuera de él (p. ej. para mostrar en qué formato debe escribirse una fecha)

Además asigno eventos onfocus y onblur genéricos para cambiar el fondo de un control cuando entramos a él.

Realmente no sé por qué no había hecho esto antes ya que el trabajo que uno se ahorra es bestial.


Yo añado alguna cosa mas, como por ejemplo poner en los inputs un atributo de tipo "_tipo" en la que marco tipos con validaciones y mensajes genéricos, integer, float, currency, etc.


Oye, ¿y esto no podrías manejarlo únicamente con algo como check_format?

// Saludos

marto
12-06-2005, 03:47:18
Hola marto,
Oye, ¿y esto no podrías manejarlo únicamente con algo como check_format?
// Saludos

En realidad, sí... pero así te ahorras más código. Si en el atributo me dices que es currency me estás diciendo el formato y también el mensaje de error error. Además, en realidad esto forma parte de un framework más grande desarrollado en java. Uso tags jsp personalizados, y es ahi donde le digo el tipo de datos, y el framework tambien me genera el onBlur en función del tipo. Lo que sucede es que la parte javascript del framework es independiente de la parte java y al revés :D