Programación en JavaScript/Funciones

De Wikilibros, la colección de libros de texto de contenido libre.
← Control/Bucles Funciones FuncionesJS →


¿Qué son las funciones?[editar]

Las funciones son uno de los elementos más importantes de cualquier lenguaje de programación actual. De hecho, Niklaus Wirth, uno de los más importantes teóricos de la programación y creador del lenguaje Pascal entre otros, llegó a indicar que todo programa no era más que la suma de código (rutinas, procedimientos o funciones, como se les quiera llamar) y datos (variables, matrices, etc...). Sea como sea, las funciones tienen un papel estelar en el desarrollo de aplicaciones en la actualidad.

Hasta ahora, hemos visto como realizar código de una forma estructurada, con sentencias de control que nos permiten dominar la ejecución del mismo fácilmente. Pero si sólo tenemos esto, solamente podremos manejar el código de forma lineal: ejecutaremos las líneas una a una, una detrás de la otra, hasta el final del programa. Es más, si quisiéramos usar un determinado código varias veces en el mismo programa tendríamos que repetir ese código varias veces, teniéndolo que adaptar a cada situación. ¿Y qué ocurre si queremos reutilizar un código en varios programas? Es un problema que se resuelven gracias a las funciones.

Las funciones son trozos de código que tienen un nombre y que podemos utilizar en cualquier parte de nuestro código con una llamada directa. Este es un buen ejemplo:

function datos_personales(nombre, apellidos, edad) 
{
   return "Hola, " + nombre + " " + apellidos + ", tienes " + edad + " años.";
}

En este caso hemos definido una función que, usando los parámetros que le hemos pasado, los combina para formar una cadena formateada, que devuelve gracias a la palabra reservada return. ¿Y cómo podemos usar este código?

 alert(datos_personales('Pepito', 'Pérez', 25));

De tal forma que primero ejecutaremos la función datos_personales con los parámetros pasados, y después la función alert, que nos permite mostrar una ventana con un mensaje en la pantalla, con el resultado devuelto por la función que hemos creado. Este sería el código completo del programa:

<html>
<head>
   <title>código de función</title>
   <script>
   function datos_personales(nombre, apellidos, edad) 
   {
      return 'Hola, ' + nombre + ' ' + apellidos + ', tienes ' + edad + ' años.';
   }
   </script>
</head>
<body>
   <script>
   alert(datos_personales("Pepito", "Perez", 25));
   </script>
</body>
</html>

Los parámetros son un elemento importante en las funciones. Se trata de datos que podemos pasar a nuestras funciones para que estas los procesen de alguna forma, lo cual dará como resultado o una salida en el navegador (texto o ventanas), o bien un resultado que se puede usar cuando llamemos a la función. Cuando indiquemos parámetros, deberemos indicar la lista completa de parámetros que vamos a usar en esa función. Al llamar a la función, deberemos hacerlo con todos los parámetros indicados. De otra forma, se produciría un error de ejecución. Los parámetros se convierten en variables de datos dentro de la función, de ahí que podamos utilizarlas e incluso modificarlas.

Generalmente, las funciones se utilizan para realizar alguna operación no visible (matemática, de cadena de caracteres, de objetos, etc...) que devuelve por medio de return, pero también se pueden visualizar elementos en el navegador usando las funciones y objetos que ya incorpora JavaScript.

function suma(dato1, dato2)
{
   return dato1 + dato2;
}

Al utilizar esta función, podemos hacerlo de varias formas:

var total = suma(1,2);  // 3
alert(suma(7,43));  // 50
document.write(total + suma(54,-7)); // 50

A lo largo de los siguientes capítulos veremos como crear y utilizar funciones, tanto propias como ajenas. Recordemos que podemos incluir código desde otro archivo y por supuesto, ese código puede contener funciones. En el siguiente capítulo veremos más ejemplos de funciones y avanzaremos en funciones internas de JavaScript.

Funciones con parámetros[editar]

Como ya indicamos en el capítulo anterior, los parámetros nos sirven para llamar a nuestras funciones con unos datos específicos para que los procese. Y en cada llamada, podemos darle unos parámetros diferentes, que harán que pueda comportarse de forma diferente, si ese es el comportamiento que le hemos programado.

var numero = 1;
var cadena = "Hi!";
var logico = true;
   
function valores(num, cad, log)
{
   document.write(num);
   document.write(cad);
   document.write(log);
}
   
valores(numero, cadena, logico);

Esta función la estamos llamando con variables como parámetros, pero también podemos llamar a la función con valores literales, es decir, valores simples directos:

valores(2, "adiós", false);

Como ya vimos en el capítulo anterior, también podemos hacer que otra función sea un parámetro:

valores(3, "que tal".length, true);

"que tal".length es una función que forma parte de los objetos de cadena de texto (todo, desde las variables hasta los literales, son objetos en JavaScript), y nos devuelve la longitud de una cadena de texto. En concreto, al hacer esta llamada nos devolverá un número '7'. Como las variables en JavaScript no tienen tipo (todas son objetos), podemos pasar cualquier valor como parámetro.

Devolución de datos[editar]

Como ya sabemos, una función puede devolver datos hacia afuera por medio de la expresión return. Naturalmente, podemos devolver cualquier tipo de datos. Sin embargo hay que tener en cuenta una serie de cuestiones:

  • Siempre se devuelven objetos, como ya hemos visto, y por lo tanto podemos devolver un objeto creado en la misma función. Normalmente, cuando creamos una variable dentro de una función, esta variable existe sólo para esa función, y desaparece en el momento en que la función termina (la variable se encuentra en la pila de memoria, y cuando la función desaparece, también lo hace la pila); pero en el caso de que devolvamos el objeto, no se devuelve exactamente la misma variable, si no que se devuelve su contenido.
  • Cuando devolvemos true ó un valor distinto que cero, para JavaScript es lo mismo, y si devolvemos false o 0, también viene a ser lo mismo. Esta es una regla estándar para muchos lenguajes como JavaScript, Java, PHP, Perl, etc...
  • No es preciso que una función devuelva nada. No es necesario usar return. Además, también es posible que en vez de devolver resultados, se modifiquen variables globales, es decir, variables creadas fuera de la función y que se usan dentro.
  • Si queremos salir de una función antes de tiempo, porque algo ha fallado o no hay nada que hacer en un caso específico, podemos simplemente escribir "return;", lo que nos permitirá salir sin más y no devolver ningún valor.

Estas consideraciones son importantes a nivel general y es importante tenerlas en cuenta. Vamos a ver como funcionan con algunos ejemplos:

function dev_variable()
{
   variable = true;
   return variable;
}
   
var var1 = dev_variable();

Como vemos, hemos declarado una variable local a la función y la hemos devuelto, pero solo se devuelve realmente el valor. Esto pasa en todos los casos (Nota técnica: cuando se devuelve un objeto, se devuelven sus datos en forma de objeto de esa clase; esto lo entenderemos mejor en el capítulo siguiente). Veamos este otro ejemplo:

function dev_true() {
   return true;
}
   
if (dev_true()) {
   alert("es true");
}
   
if (true) {
   alert("también es true");
}
   
if (1)
{
   alert("este también es true");
}

Por último, veamos cómo salir de una función sin necesidad de devolver nada en cualquier momento:

function salir()
{
   document.write("hola");
   document.write("que pasa");
   return;
   alert("adiós");
}

salir();

En este ejemplo, la última linea dentro de la función (alert) no se ejecutará nunca porque hemos salido sin más en la linea anterior al ejecutarse la instrucción return.

Funciones recursivas[editar]

Las funciones recursivas son aquellas que se llaman a sí mismas. Existen multitud de técnicas para desarrollar este tipo de funciones, ya que sus usos son muy diversos, pero fundamentalmente hay que tener en consideración que son funciones peligrosas, porque si no controlamos su ejecución, se estarán ejecutando indefinidamente, como en el caso de los bucles infinitos. La diferencia con los bucles infinitos es que dependiendo de la implementación del intérprete de JavaScript, es posible que rompamos la pila de memoria, que ya vimos antes, con lo que además de colgar el navegador, podemos generar una excepción de memoria y un error grave del sistema. Para evitarlo, claro está, debemos estudiar bien la lógica de la función para construirla adecuadamente. Por ejemplo, si queremos calcular el factorial de un número, podemos hacerlo con una función recursiva:

function factorial(numero)
{
   if (numero == 1 || numero == 0)
      return 1;
   else
      return numero*factorial(numero - 1);
}
   
document.write(factorial(4));

Supóngase la llamada a esta función para N=4, es decir factorial(4). Cuando se llame por primera vez a la función, la variable numero valdrá 4, y por tanto devolverá el valor de 4*factorial(3); pero factorial(3) devolverá 3*factorial(2); factorial(2) a su vez es 2*factorial(1) y dado que factorial(1) es igual a 1 (es importante considerar que sin éste u otro caso particular, llamado caso base, la función recursiva no terminaría nunca de llamarse a sí misma), el resultado final será 4*(3*(2*1)).