Funciones en JavaScript

By Mario Castillo Monge

Introducción

Las funciones son la esencia de prácticamente todo lo útil que harás con Java Script. En términos generales, las funciones ofrecen la capacidad de dividir lógicamente un programa en varias secciones, cada una de las cuales implementa una funcionalidad específica.Las funciones son una característica central de este lenguaje, y una buena parte del atractivo de Java Script se debe a la forma particular en la que te permite crear y utilizar funciones. Si ya has hecho algo de programación en lenguajes como PHP o Java, te sentirás como en casa con las funciones de Java Script; si no, no hay razón para preocuparse. Las funciones son críticas, pero no es dífícil adaptar la mente a ellas. Este artículo explica por qué desearás comprender las funciones, luego ingresa a su sintaxis y te muestra cómo crearlas y utilizarlas.

En este artículo, los ejemplos de funciones están disponibles para ser descargados, y a la vez están enlazados a páginas de muestra apropiadas.

La estructura de este artículo es la siguiente:

Qué y Por Qué

Ciertamente, no deseas tener que refrescar la memoria cada que vez que necesitas hacer un cálculo específico; es mucho mejor codificar los pasos de ese cálculo sólo una vez, reunirlos como una función calculateSomething y entonces usar ese código cada vez que necesites hacer lo mismo. El simple acto de reunir un grupo de comandos significa que puedes concentrarte en las actividades que tu código implementa sin preocuparte de los detalles de los pasos internos de esas actividades. Puedes pensar en las funciones que escribes como una capa que se agrega sobre el núcleo de JavaScript; estás creando nuevos comandos que son más expresivos y comprensibles en el entorno de tu propia aplicación

Con eso en mente, el por qué de las funciones tiene una respuesta muy sencilla: son los bloques de construcción básicos que te permiten estructurar tu código para mejorar la comprensión de su propósito, y reutilizar las funciones que ya has escrito para evitar repetir el mismo código varias veces. Tu programa será más fácil de escribir y probar si lo divides en pequeñas piezas, cada una con una tarea definida

Además, dividir tu código en funciones bien diseñadas hace mucho más fácil su mantenimiento futuro. Imagina, por ejemplo, que las reglas del horario de ahorro de energía son cambiadas cada año. Si has hecho ese cálculo ochenta y cinco veces en todo tu proyecto, vas a introducir nuevos errores al actualizar el código en cada una de esas piezas de código; es un proceso repetitivo, manual, y propenso a fallar. Por otro lado, cambiar una unica función calculateDaylightSavings te permite transmitir ese cambio a través de todo el resto del programa, en forma muy parecida a cómo una hoja de estilo CSS actúa sobre toda una página web. Así, las funciones hacen que el mantenimiento sea muchos menos propenso al error, y más fácil de implementar exitosamente.

Sintaxis de una Función

Definir tus propias funciones es una tarea sencilla. Por ejemplo, construyamos una función que genera un color de fondo para un elemento de una página web.

function setElementBackground() {  var red = Math.floor(Math.random() * 256);  var green = Math.floor(Math.random() * 256);  var blue = Math.floor(Math.random() * 256);  var obj = document.getElementById('element_to_change');  if ( obj ) {    obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';  }}

Sin preocuparte mucho por el código ejecutado por la función, me gustaría que prestes atención en este momento a 4 características importantes de la sintaxis de la función:

  1. Una declaración de función siempre empieza con la palabra clave function, lo cual tiene sentido.
  2. El siguiente punto es el nombre de la función, en este caso setElementBackground (Generalmente uso camelCase para los nombres de las funciones). El nombre de la función es importante, porque es lo que debes recordar para utilizarla y reutilizar su código. Asegúrate de que sea una descripción precisa de lo que la función hace; estoy seguro de que estarás de acuerdo en que setElementBackground es un nombre de función sumamente mejor y más descriptivo que algo como coloursAreNice o crazySetter.
  3. Inmediatamente después del nombre de la función viene un par de paréntesis. Dentro de ellos viene la lista de argumentos de la función, la cual te permite hacer la función más genérica y reutilizable; puedes aplicarla a más situaciones más fácilmente. Este es un concepto poderoso, pero opcional, por lo que lo explicaré con más detalle en la siguiente sección.
  4. Finalmente viene un par de llaves que contienen código: esto significa un bloque de código en JavaScript. Todo lo que está en el bloque será ejecutado cuando la función sea llamada, en orden, en la misma forma que cualquier otra porción de código en JavaScript que hayas escrito.

Utilizando una Función

Ahora que hemos definido la función, para llamarla desde alguna parte del código podrías simplemente escribir:

setElementBackground();

¡Y eso es todo! Ya no tienes que preocuparte por los detalles internos de setElementBackground; ya has escrito el código, por lo tanto ahora puedes usarlo donde quieras, y disfrutar los (variables) beneficios de su reutilización.

Ahora, la función que he escrito es completamente autocontenida. Realiza una actividad, luego sale; no necesita ingreso de información desde el código que la llamó, ni devuelve al código que la llamó alguna información sobre lo que sucede. JavaScript, por supuesto, permite escribir código un poco más comunicativo y flexible que ese, así que veamos cómo podemos manejar el ingreso y salida de información en las funciones.

Argumentos

Ingresar información a una función para influenciar su comportamiento es una gran forma de hacerla más flexible y útil en una amplia variedad de situaciones. Por ejemplo, he codificado en forma muy cerrada el id del elemento cuyo color de fondo es cambiado en la función setElementBackground; sería mejor poder especificar diferentes elementos en la página web cada vez que llame a la función, y así podría reutilizarla para diferentes elementos, en vez de repetir todo ese código. Los argumentos de la función son la solución.

Hace un momento, indiqué que la definición de función contiene un par de paréntesis inmediatamente después del nombre de la función. Esta es la lista de argumentos de la función. Para recibir información del código que la llama, sólo especifica una lista separada por comas de las variables que tu función aceptará. Puedes especificar tantas o tan pocas como desees, y los nombres que uses en la lista de argumentos pueden ser mencionados en el cuerpo de la función en la misma forma que cualquier otra variable. La función setElementBackground actualizada se ve así (revisa el primer ejemplo de mejora ):

function setElementBackground( elementID ) {  var red = Math.floor(Math.random() * 256);  var green = Math.floor(Math.random() * 256);  var blue = Math.floor(Math.random() * 256);  var obj = document.getElementById( elementID );  if ( obj ) {    obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';  }}

Llamar a esta función con un element ID entregado como argumento es muy simple:

setElementBackground( 'element_to_change' );

Si accidentalmente llamas a la función sin indicar un argumento, toma el valor undefined. Puedes probar esto en el cuerpo de tu función para crear alguna protección contra errores de uso no intencionales:

if ( elementID == undefined) {  // esto dará como resultado `true` si la variable `elementID`  // no ha sido entregada.  // Luego puedes escribir código dentro de este bucle if  //para evitar que el programa genere errores.}

Un punto confuso pero interesante acerca de los argumentos de una función es que los nombres de variables en la lista de argumentos no tienen nada en común con los nombres de variables entregados a la función. Si elementID es definido como el argumento de la función, JavaScript crea una variable dentro de la función llamada elementID que no tiene efecto en ninguna variable fuera de la función - puedes tener otra función fuera de la función con el mismo nombre, y su valor no se alteraría como resultado de cualquier indicación en la función original. Por ejemplo:

var elementID = "No change!";setElementBackground( 'element_to_change' );alert( elementID ); // Alerts "No change!";

esto tiene un importante efecto colateral. JavaScript crea una nueva variable dentro de la función pero los cambios en su argumento intern no tienen efecto sobre ninguna variable entregada a la función. Hablaré un poco más de este concepto (llamado scope) en los artículos sobre Objetos y Buenas Prácticas en JavaScript, pero por ahora, veamos un ejemplo rápido. Definiré una función substring que acepte una cadena y un punto de inicio:

function substring( obj, start ) {  obj = obj.substring(8);}var myString = "Esto es una cadena!";substring(myString, 8);alert(myString); // muestra el mensaje de alerta "esto es una cadena!"

Pese a que la variable obj es reasignada dentro de la función al resultado del método interno substring, myString no es afectada en lo más mínimo; sólo la copy de myString dentro de substring fue cambiada. La variable externa no cambia con nada de lo que suceda.

Esto da lugar a una pregunta sobre comunicación: si cambiar el valor de los argumentos no tiene efecto fuera de la función, ¿cómo devuelves información de una función al código que la llamó? Veamos esto ahora.

Mostrando valores calculados

Es muy común que una función haga algunos cálculos, y devuelva el resultado al código que la llama, para ser utilizdo donde convenga. Podría se muy útil, por ejemplo, para nuestra función setElementBackground devolver un array de los valores de color para usarlo donde convenga. Es un simple asunto de usar la palabra clave return de JavaScript, como se muestra aquí:

function setElementBackground( elementID ) {  var red = Math.floor(Math.random() * 256);  var green = Math.floor(Math.random() * 256);  var blue = Math.floor(Math.random() * 256);  var obj = document.getElementById( elementID );  if ( obj ) {    obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';  }  return [ red, green, blue ];}

observa el segundo ejemplo de mejora en acción.

Este simple agregado significa que ahora puedes llamar la función en forma tal que se guarde su resultado en una variable:

var my_result = setElementBackground('element_to_change');

Incluso si tu función no necesita devolver un valor, o no tiene un valor para devolver, es una buena práctica indicar el éxito o error devolviendo los valores true o false, respectivamente. Con eso en mente, cambiaré setElementBackground para devolver false si el elementID entregado en verdad no existe:

function setElementBackground( elementID ) {  var red = Math.floor(Math.random() * 256);  var green = Math.floor(Math.random() * 256);  var blue = Math.floor(Math.random() * 256);  var obj = document.getElementById( elementID );  if ( obj ) {    obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';    return [ red, green, blue ];  } else {    return false;  }}

observa el tercer ejemplo de mejora en acción.

Esto te permite verificar que el código se ejecutó correctamente probando el valor que devuelve:

if ( !setElementBackground('element_does_not_exist') ) {  alert("Something went wrong!  `element_does_not_exist` doesn't exist!");}

Adicionalmente, toma en cuenta que la palabra clave return pone fin a la ejecución del código justo cuando es llamada, regresando la ejecución al punto en el cual tu función fue llamada. El código que se escriba luego de la llamada a return no es ejecutado, simplemente es ignorado.

Sumario

Con eso, ahora sabes prácticamente todo lo que necesitas para empezar a incluir funciones a lo largo de todo tu código. Las funciones son una parte básica en todo buen código JavaScript y tus programas estarán mejor organizados, serán más claros, más legibles, y más fáciles de comprender si tomas la opción de agrupar el código en funciones bien nombradas que puedan reutilizarse.

Preguntas de práctica

  • ¿Qué son las funciones? ¿Por qué son muy útiles?
  • ¿Cómo defines una función?
  • ¿Cómo ingresas información en una función? ¿Porqué querrías hacerlo? Inversamente, ¿cómo puedes recibir información de una función?
  • ¿No sería interesante si pudieras ingresar un array de colores en `setElementBackground`? Intenta modificar el código para aceptar otro argumento, y usa esa variable dentro de la función para anular el color de fondo aleatorio.

Acerca del autor

Foto del autor del artículo, Mike West

Mike West es un estudiante de filosofía ingeniosamente disfrazado como un experto y exitoso desarrollador web. Ha estado trabajando cn la web por más de una década, y más recientemente ha sido miembro del equipo responsable de construir los sitios europeos de noticias de Yahoo!.

Luego de dejar las amplias planicies suburbanas de Texas en 2005, Mike se estableció en Munich, Alemania, donde cada día lucha un poco menos con el idioma. mikewest.org es su hogar en la web, donde (lentamente) está reuniendo sus escritos y enlaces para la posteridad. Almacena su trabajo de código en GitHub.

This article is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.