Javascript, parte 5: Funciones

Una función nos permite separar una tarea de forma independiente. Al igual que las variables/constantes tienen nombres que permiten identificarlas.

Las funciones están divididas en tres partes:

  • Parámetros
  • Bloque de código, lo que hace la función
  • Resultado

Estructura de una función

Tenemos dos formas de definir la estructura de una función.

A través de una función tradicional:

function miFuncion(){
    //Lo que hace la función
}

O una función flecha:

const miFuncion = () => {
    //Lo que hace la función
}

Ambas formas son correctas, aunque tienen algunas diferencias que profundizaremos más adelante. De momento sólo usaremos funciones flecha.

Entonces, como pudimos ver una función flecha, es una constante a la cual igualaremos en apertura y cierre de paréntesis, y luego con una flecha => y entre llaves, indicaremos lo que hace la función.

Por ejemplo:

const saludar = () => {
    console.log("Hola, soy una función saludándote. Que tengas un buen día.");
}

Dentro del cuerpo de una función indicaremos lo que hará ésta al ser llamada. Es decir que el código de una función no va a ejecutarse, sino que quedará encapsulado.

Para llamar ejecutar una función debemos indicar su nombre seguido de los paréntesis:

saludar();

Esto nos devolverá por consola: Hola, soy una función saludándote. Que tengas un buen día.

Parámetros

Un parámetro es el valor de entrada a una función. Las funciones pueden tener un parámetro, dos, tres… Incluso no tener ninguno, los parámetros no son obligatorios.

Por ejemplo podríamos cambiar la función anterior para ingresar el nombre del usuario:

const saludar = (nombre) => {
    console.log(nombre + ", hola, soy una función saludándote. Que tengas un buen día.");
}

saludar("Patricia");

Vale, aclarar que las funciones nos dan la posibilidad de reutilizar código. Por tanto podríamos llamar a la misma cuantas veces quisiéramos y con distintos parámetros:

const saludar = (nombre) => {
    console.log(nombre + ", hola, soy una función saludándote. Que tengas un buen día.");
}

saludar("Patricia");
saludar("Agustina");
saludar("Juan");

Esto nos devolverá por pantalla:

Patricia, hola, soy una función saludándote. Que tengas un buen día.
Agustina, hola, soy una función saludándote. Que tengas un buen día.
Juan, hola, soy una función saludándote. Que tengas un buen día.

Además, las funciones pueden tener más de un parámetro. Por ejemplo:

const saludar = (nombre, apellido) => {
    console.log(nombre + " " + apellido +  ", hola, soy una función saludándote. Que tengas un buen día.");
}

Aunque en este último caso, al llamar a la función debemos agregar ambos parámetros:

saludar("Fernando", "Gaitán");

Como se puede ver en el ejemplo los parámetros se separaran con coma.

Parámetros con valores por defecto

Podemos agregar parámetros no obligatorios. Es decir que al llamar una función pasarle o no un determinado parámetro. Sin embargo, para esto también debemos definir un valor que el parámetro tendrá en caso de no pasarle uno.

const saludar = (nombre="Desconocido") => {
    console.log(nombre +  ", hola, soy una función saludándote. Que tengas un buen día.");
}

Por tanto al llamar a esta función en este caso, podemos pasarle el parámetro nombre o no. Si no lo hacemos por defecto tomará el valor: «Desconocido»:

saludar("Fernando");
saludar();

En el la primer línea devolverá:

Fernando, hola, soy una función saludándote. Que tengas un buen día.

Y en la segunda:

Desconocido, hola, soy una función saludándote. Que tengas un buen día.

Retorno de una función

Una función a su vez nos devuelve la posibilidad de retornar valores a través de la palabra reservada return.

const obtenerPromedio = (nota1, nota2, nota3) => {
    let suma = nota1 + nota2 + nota3;
    let promedio = suma / 3;
    return promedio;
}

let promedio = obtenerPromedio(10, 7, 4);
console.log(promedio);

Como podemos ver en el ejemplo anterior, si quisiéramos obtener el promedio de las tres notas de un alumno nos llevaría varios pasos.

Sin embargo podríamos crear una función que nos devuelva sólo el resultado, y luego reutilizarla cada vez que lo necesitemos.

Para redondear números podemos reemplazar la función por el método toFixed():

const obtenerPromedio = (nota1, nota2, nota3) => {
    let suma = nota1 + nota2 + nota3;
    let promedio = suma / 3;
    return promedio.toFixed(2);
}

Variables/constantes locales

Podemos declarar variables o constantes de forma local para usarlas dentro de una función. Sin embargo, éstas no podrán accederse fuera de este contexto.

Si por ejemplo tuviésemos algo como esto:

const miFuncion = () => {
    const numero = 10;
}

console.log(numero);

Al llamar a esa constante numero, fuera de la función nos devolverá un error: «numero is not defined» (numero no está definido)

Funciones dentro de funciones

Siguiendo con el ejemplo anterior de las notas de los alumnos:

const obtenerPromedio = (nota1, nota2, nota3) => {
    let suma = nota1 + nota2 + nota3;
    let promedio = suma / 3;
    return promedio.toFixed(2);
}

Ahora supongamos que queremos verificar mediante su promedio si la/el alumna/o promocionó la materia, es decir obtuvo 7 o más en su nota final:

const verificarPromocion = (nota1, nota2, nota3) => {
    let promedio = obtenerPromedio(nota1, nota2, nota3);
    let resultado;
    if(promedio >= 7){
        resultado = true;
    }else{
        resultado = false;
    }
    return resultado;
}

Como vemos en el ejemplo anterior, podemos reutilizar dentro de una función el resultado de otra y de esta manera ahorrarnos unas líneas de código:

let is_promocion = verificarPromocion(10, 5, 7);
if(is_promocion){
    console.log("La/el alumna/o promocionó la materia");
}else{
    console.log("La/el alumna/o NO promocionó la materia");
}

Condicional ternario

Podríamos simplificar el código de la función:

const verificarPromocion = (nota1, nota2, nota3) => {
    let promedio = obtenerPromedio(nota1, nota2, nota3);
    let resultado;
    if(promedio >= 7){
        resultado = true;
    }else{
        resultado = false;
    }
    return resultado;
}

Por:

const verificarPromocion = (nota1, nota2, nota3) => {
    let promedio = obtenerPromedio(nota1, nota2, nota3);
    return (promedio >= 7);
}

La función devuelve un resultado boolean, pero ya de por sí la condición también lo hace, por eso lo retornamos directamente:

return (promedio >= 7);

Ahora si quisiéramos devolver un valor string, podríamos hacer algo como esto:

const verificarPromocion = (nota1, nota2, nota3) => {
    let promedio = obtenerPromedio(nota1, nota2, nota3);
    let resultado;
    if(promedio >= 7){
        resultado = "La/el alumna/o promocionó la materia";
    }else{
        resultado = "La/el alumna/o NO alcanza el promedio para promocionar la materia";
    }
    return resultado;
}

O resumirlo con un condicional ternario:

const verificarPromocion = (nota1, nota2, nota3) => {
    let promedio = obtenerPromedio(nota1, nota2, nota3);
    return (promedio >= 7) ? "La/el alumna/o promocionó la materia" : "La/el alumna/o NO alcanza el promedio para promocionar la materia";
}