Funciones

Introducción

Muchas veces necesitamos realizar la misma acción en distintos lugares de nuestro código.

Por ejemplo, necesitamos mostrar un mensaje cuando el usuario se loguea y cuando cierra su sesión.

Las funciones son los principales "bloques de construcción" de un programa. Nos permiten que el código sea llamado varias veces evitando repetir el mismo código.

Ya vimos algunos ejemplos de funciones nativas como alert("Hola"), prompt("Inserta tu edad") o confirm("Estás seguro de comprar el pasaje?"). Pero nosotros podemos crear nuestras propias funcionas también.

Declaración de una Función

Para crear una función usamos una declaración de función.

Se ve de la siguiente manera:

function mostrarMensaje() {
  alert('Hola a todos!')
}

La palabra reservada function se escribe primero, después el nombre de la función, posteriormente una lista de parámetros dentro de los paréntesis (sin parámetros en el ejemplo anterior) y finalmente el código de la función, también llamado como cuerpo de la función, encerrado entre llaves.

Nuestra nueva función puede ser llamada por su nombre: mostrarMensaje().

Por ejemplo:

function mostrarMensaje() {
  alert('Hola a todos!')
}

mostrarMensaje()
mostrarMensaje()

La llamada a mostrarMensaje() ejecuta el código de la función. Donde mostraremos el mensaje 2 veces.

Este ejemplo claramente demuestra uno de los principales propósitos de las funciones: evitar duplicación de código.

Si necesitasemos cambiar el mensaje o la manera en que se muestra, es suficiente con modificar el código en un solo lugar: en la declaración de la función.

Variables locales

Una variable es declarada dentro de una función si solo es visible dentro de esa función.

Por ejemplo:

function mostrarMensaje() {
  let mensaje = 'Hola a todos!' // variable local
  alert(mensaje)
}

mostrarMensaje() // Hola a todos!

alert(mensaje) // <-- Error! La variable es local a la función

Variables externas

Una función puede acceder una variable externa o fuera de si misma.

let nombre = 'Matias'

function mostrarMensaje() {
  let mensaje = 'Hola, ' + nombre
  alert(mensaje)
}

mostrarMensaje() // Hola, Matias

La función tiene acceso completo a la variable externa. La puede modificar también.

let nombre = 'Matias'

function mostrarMensaje() {
  nombre = 'Caro' // Cambiamos la variable externa

  let mensaje = 'Hola, ' + nombre
  alert(mensaje)
}

alert(nombre) // Matias, antes de la llamada a la función

mostrarMensaje()

alert(nombre) // Caro, después de la llamada a la función

La variable externa solo es usada si no hay ninguna local.

Si una variable es declarada con el mismo nombre dentro de la función, esta última es utilizada en vez de la variable externa.

Por ejemplo, en el código debajo, la función usa la variable local nombre y la que esta por fuera es ignorada:

let nombre = 'Matias'

function mostrarMensaje() {
  let nombre = 'Caro' // declaramos una variable local

  let mensaje = 'Hola, ' + nombre // Caro
  alert(mensaje)
}

// La función creará y usará su propia variable nombre
mostrarMensaje()

alert(nombre) // Matias, permanece igual ya que la función no modifica la variable externa

Parámetros

Podemos pasar datos arbitrarios a las funciones usando parámetros (también llamados argumentos de la función).

En el ejemplo debajo, la función tiene 2 parámetros: de y texto.

// parámetros: de, texto
function mostrarMensaje(de, texto) {
  alert(de + ': ' + texto)
}

mostrarMensaje('Leila', 'Hola!') // Leila: Hola! (*)
mostrarMensaje('Leila', 'Qué onda?') // Leila: Qué onda? (**)

Cuando la función es llamada en las lineas (*) y (**), los valores dados son copiados a variables locales de y texto. Posteriormente la función las usa por dentro.

Acá vemos un ejemplo más: tenemos una variable de y se la pasamos a la función. Importante: la función cambia el parámetro from pero el cambio no es reflejado fuera de ella, porque la función siempre recibe una copia de este valor.

function mostrarMensaje(de, texto) {
  de = '*' + de + '*' // mejorar como se visualiza el parámetro "de"

  alert(de + ': ' + texto)
}

let de = 'Ale'

mostrarMensaje(de, 'Hola') // *Ale*: Hola

// El valor de "de" es el mismo, la función modifica una copia local
alert(de) // Ale

Valores por defecto

Si un parámetro no es provisto, entonces este valor se vuelve undefined.

Por ejemplo, la función que ya declaramos function mostrarMensaje(de, texto) puede ser llamada con un solo parámetro:

mostrarMensaje('Caro')

Eso no es un error. Tal llamada mostrara: "Caro: undefined". No hay texto, entonces asume que texto === undefined.

Si queremos usar un valor por defecto para el texto en este caso, lo podemos especificar después de su declaración usando =. Por ejemplo:

function mostrarMensaje(de, texto = 'ningún texto provisto') {
  alert(de + ': ' + texto)
}

mostrarMensaje('Ale') // Ale: ningún texto provisto

Ahora cuando el parámetro texto no es enviado, entonces obtendra el valor "ningún texto provisto"

Acá "ningún texto provisto" es un string, pero puede ser una expresión compleja, la cual es evaluada y asignada solamente si el parámetro no fue asignado. Así que esto también es posible:

function mostrarMensaje(de, texto = otraFuncion()) {
  // otraFuncion() es ejecutada solamente si no hay ningún texto
  // el resultado de la función será el nuevo valor de texto
}

Devolviendo un valor

Una función puede devolver un valor como resultado al código donde fue ejecutada.

Este ejemplo sencillo mostrará una función que suma 2 valores:

function suma(a, b) {
  return a + b
}

let resultado = suma(1, 2)
alert(resultado) // 3

La palabra reservada return puede ser colocada en cualquier lugar dentro de la función. Cuando la ejecución llega a return, la función deja de correr y devuelve el valor a donde fue llamada la función.

Hay varias ocurrencias de un return dentro de una sola función. Por ejemplo:

function verificarEdad(edad) {
  if (edad > 18) {
    return true
  } else {
    return confirm('Tenés permisos de tus padres?')
  }
}

let edad = prompt('Qué edad tenes?', 18)

if (verificarEdad(edad)) {
  alert('Acceso permitido')
} else {
  alert('Acceso negado')
}

También es posible usar return sin devolver ningún valor. Esto causa que la función frene inmediatamente. Por ejemplo:

function mostrarPelicula(edad) {
  if (!verificarEdad(edad)) {
    return
  }

  alert('Mostrando la película +18') // (*)
}

En el código de arriba, si verificarEdad(edad) devuelve falso que negado nos da true por ende se ejecuta el condicional y mostrarPelicula no seguirá a ejecutar el alert.

Nombrando una función

Las funciones son acciones. Asi que usualmente su nombre es un verbo. Debe ser corto, y lo más preciso posible describiendo lo que la función hace, así que alguien leyendo el código obtiene una indicación de lo que función hace.

Es una práctica común empezar una función con un verbo como prefijo que vagamente describa la acción. Debe haber un acuerdo dentro del equipo para el nombramiento de estos prefijos.

Por ejemplo las funciones que empiezan con "mostrar" usualmente muestran algo.

Una función empezando con:

  • "obtener…" – devuelven un valor,

  • "calcular…" – calculan algo,

  • "crear…" – crean algo,

  • "verificar…" – chequen algo y devuelven un booleano.

Ejemplo de tales nombres:

mostrarMensaje(..)    // muestra un mensaje
obtenerEdad(..)       // devuelve la edad ( la obtiene de alguna manera)
calcularSuma(..)      // calcula una suma y devuelve un valor
crearFormulario(..)   // crea un formulario
verificarPermisos(..) // verifica permisos, devuelve true o false

Con los prefijos en su lugar, un vistazo al nombre de la función nos da un claro entendimiento de que tipo de trabajo hace y que tipo de valor devuelve.

Conclusión

La declaración de una función se ve así:

function nombre(parametros, delimitados, por, comas) {
  /* código */
}

Características:

  • Los valores son pasados a una función como parámetros que son copiados a ella como variables locales

  • Una función puede acceder variables externas. Pero solo funciona de adentro hacia fuera. El código fuera de la función no puede acceder a las variables locales de esta última.

  • Una función puede devolver un valor. Sino lo hace, entonces el resultado es undefined

Para que el código sea más simple y fácil de entender, es recomendable usar principalmente variables locales y parámetros en la función y no variables por fuera de la misma.

Siempre es más fácil de entender una función que recibe parámetros, trabaja con ellos y devuelve un resultado que una funcioón que no recibe parámetros y modifica variables por fuera de ella como un side-effect.

Nombrando funciones:

  • El nombre debe describir claramente lo que la función hace. Cuando vemos la llamada a la función en el código, un buen nombre instantaneamente nos describe que hace y que devuelve.

  • Una función es una acción, por ende los nombres de las funciones son verbos. Existen varios prefijos conocidos como : crear..., mostrar..., obtener..., verificar... y más. Usalos como pistas de lo que la función hace.

Continuar con Ejercicio Integrador

Last updated