martes, junio 19, 2012

Curso de desarrollo web, Parte XXXVII: Las funciones

¡Bien! Aquí estamos, publicando el curso desde España de nuevo. Quien sea asíduo del blog habrá comprobado que aún la cosa está un poco caótica, ¡pero es que no estoy teniendo tiempo para casi nada! Aún así, aquí sigo al pie del cañón, sólo pido un poco de paciencia para arreglar los post anteriores y dejarlos correctamente. Pero, de momento, seguimos adelante con el curso de desarrollo web.
Vamos a tomar un caso hipotético. Recordaremos que hace unas semanas uno de los ejercicios consistía en crear una pequeña aplicación que descubriera si el año introducido era bisiesto o no. Aunque en su día no publiqué la resolución, sería algo como esto:
var anio = prompt("Introduzca un año:");

if((anio % 4 == 0 && anio % 100 != 0) || anio % 400 == 0)
{
document.write("Es bisiesto.");
}
else
{
document.write("No es bisiesto.");
}

Bueno, imaginemos ahora que nos vemos en la tesitura de que queremos usar en muchas ocasiones a lo largo de nuestra aplicación este código. ¿Qué hacemos? ¿Repetimos el código en cada ocasión? La verdad es que sería bastante latoso y, incluso aunque copypasteemos una y otra vez, nos quedaría un código enorme, y una de las cosas que intentaremos en nuestros programas es que los programas no se vean muy enrevesados. Entonces, ¿qué podemos hacer para no tener que estar repitiendo el código una y otra vez? La respuesta es la siguiente: funciones.
A lo largo de las anteriores entregas hemos ido hablando de distintas funciones y métodos que tiene el JavaScript, algunos como el alert o el prompt completamente independientes (funciones), y otros como el toString o el indexOf que venían acompañando a un objeto (métodos). Hoy vamos a aprender a hacer nuestras funciones personalizadas.
Para crear una función, primero tenemos que escribir su signatura. Para ello, escribiremos por ejemplo:

function esBisiesto(year)

Esas línea es la "signatura" de la función. En primer lugar viene la palabra reservada "function" que indica que vamos a empezar a escribir una función. Le sigue el nombre de la función, el cual, como podéis ver, puede ser cualquiera que se nos ocurre. Finalmente, entre paréntesis, indicaremos el número de parámetros que necesita la función que se le pase y unos nombres para identificarlos dentro de la función. De este modo, dentro de la función podremos usar el parámetro "year" como si fuera una variable, ya que se supone que, cuando llamemos a la función, le daremos un valor a "year".
Cabe destacar que, igual que ocurría con las funciones y métodos que ya hemos visto, las funciones personalizadas pueden tener más de un parámetro. Por ejemplo, podríamos tener:

function esBisiesto(year, month)

No tendría mucho sentido, ya que no necesitamos el mes para descubrir si un año es bisiesto, pero lo que quiero decir es que, con esa signatura, podremos usar dentro de la función tanto el valor de "year" como el valor de "month".
En segundo lugar, escribiremos el cuerpo de la función, que podrá ser algo así:

function esBisiesto(year)
{
   if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
       return true;
    }
    else
    {
         return false;
    }
}

Vemos en primer lugar que, como ya había explicado con anterioridad, el usar espacios o tabuladores para ordenar nuestro código puede ser muy útil, ya que ahí ya vemos llaves "encadenadas" que nos pueden dar bastantes quebraderos de cabeza si no ordenamos el código.
En segundo lugar quiero que se fijen cómo, tras poner la signatura y abrir la llave que englobará la función completa, empezamos a usar el parámetro "year" como una variable.
Finalmente, depende de cual de las opciones se den, usamos la palabra reservada return para devolver un valor, en este caso un booleano, aunque podríamos haber devuelto un entero, una String o incluso un array si hubiéramos querido. Además, si incluímos la palabra return sin ningún valor detrás, sino seguido ded un punto y coma (return;), la función se acabará abruptamente sin devolver ningún resultado, algo que nos puede interesar en alguna ocasión.
De este modo, el código de arriba podría resumirse en el siguiente:


var anio = prompt("Introduzca un año:");


var check = esBisiesto(anio);

if(check)
{
document.write("Es bisiesto.");
}
else
{
document.write("No es bisiesto.");
}


Vemos cómo en la variable "check" recogemos el valor que devolverá la función "esBisiesto" cuando le pasamos como parámetro la variable "anio" (que, al entrar en la función, se convertiría en "year" en su interior). Pero también podríamos hacerlo más simple, así:


var anio = prompt("Introduzca un año:");

if(esBisiesto(anio))
{
document.write("Es bisiesto.");
}
else
{
document.write("No es bisiesto.");
}


No necesitamos ni siquiera guardar el valor en una variable, sino que podemos evaluarlo según salga de la función.
Y tal vez os estéis preguntando, ¿y esta función dónde estará en este código? Pues podría ser perfectamente así:


<script type="text/javascript">
var anio = prompt("Introduzca un año:");

if(esBisiesto(anio))
{
document.write("Es bisiesto.");
}
else
{
document.write("No es bisiesto.");
}



function esBisiesto(year)
{
   if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
       return true;
    }
    else
    {
         return false;
    }
}
</script>


Cuando el navegador se encuentra la palabra reservada "function" ignora su interior y no lo ejecuta a menos que encuentre en algún lugar del documento una "llamada" a esa función (como el "esBisiesto(anio)" que tenemos ahí). Incluso la función, como vemos aquí, puede estar después de su llamada, ya que el navegador, al encontrarse con una llamada a la función, buscará por todo el documento dónde está dicha función para poder ejecutarla (y fallará en caso de no encontrarla).
Finalmente, dejar claro que las funciones no tienen por qué devolver algo siempre (o sea, usar la palabra "return"), al menos no en JavaScript, de modo que este código podría haber sido tan simple como:


<script type="text/javascript">
var anio = prompt("Introduzca un año:");

esBisiesto(anio);



function esBisiesto(year)
{
   if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
       document.write("Es bisiesto.");
    }
    else
    {
         document.write("No es bisiesto.");
    }
}
</script>


En este código, "esBisiesto" lo que hace es escribir en pantalla si un código es bisiesto o no, dependiendo del valor que se le pase por parámetro. La función no devuelve un valor sino que es directamente ella la que escribe en pantalla. En ocasiones nos será más útil usar un método u otro, será cuestión del usuario decidirlo. Otra manera de conseguir el mismo resultado podría ser:


<script type="text/javascript">
var anio = prompt("Introduzca un año:");

document.write(esBisiesto(anio));



function esBisiesto(year)
{
   if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
       return "Es bisiesto.";
    }
    else
    {
         return "No es bisiesto.";
    }
}
</script>


Tal como dije, con "return" se puede devolver cualquier tipo de valor, no sólo booleanos, así que en esta opción, al devolver un String con el resultado que queremos, simplemente le diremos que escriba en pantalla el valor resultante de la función.
Y, de momento, esto es todo sobre las funciones. Aunque puedan parecer un poco liosas, os aseguro que os será más que útiles cuando empecéis a programar en serio.

EJERCICIO


Esta semana nuestro ejercicio será, como no podía ser de otro modo, programar una función. Cuando un usuario introduzca un nombre en nuestra página, llamaremos a una función que cambiará todas las letras de mayúsculas a minúsculas o viceversa. De este modo, "Hola" debería convertirse en "hOLA" y "Me llamo Eme" debería pasar a ser "mE LLAMO eME". Finalmente mostraremos por pantalla el resultado de la función.

Y eso es todo por esta semana. A ver si empiezo a publicar soluciones a lo largo de esta semana. ¡Ya les iré contando!

No hay comentarios: