Que es una High Order Function (HOF)

Que es una High Order Function (HOF)

Bienvenido a esta nueva entrada del blog donde aprenderemos qué son las funciones de orden superior (High Order Functions).

La definición de una función de orden superior es la siguiente

Es una función que puede recibir una función como argumento o una función que devuelve otra función.

Como podemos ver la definición es breve y sencilla de entender, pero el problema comienza cuando intentamos entender la importancia y utilidad que le podemos dar.

Bien, para ello vamos a realizar algunos ejemplos muy sencillos con varios casos de uso.

Empezaremos con una función que recibe otra función como argumento, ya que pienso que este tipo se usa a diario y casi sin darnos cuenta.

El ejemplo mas sencillo se puede encontrar, por ejemplo en los métodos .map() o .filter() de un array.

const square = num => num ** 2;
const numbers = [1, 2, 3 ,4 ,5];
console.log(numbers.map(function(item) {
   return item ** 2;
}));                                             // [1, 4, 9, 16, 25]

console.log(numbers.map(item => square(item)));  // [1, 4, 9, 16, 25]

console.log(numbers.map(square));                // [1, 4, 9, 16, 25]

Con el ejemplo anterior ya vamos entendiendo la potencia de las funciones de orden superior.

A continuación vamos hacer un ejemplo que simule el método .map().

const getAscii = value => value.toString().charCodeAt();
    
const getArrAscii = (arr, fn) => {
    let iArr = [];
    const size = arr.length;
    for (let cont = 0; cont < size; cont++) {
        iArr.push(fn(arr[cont]))
    }
    return iArr;
}

console.log(getArrAscii(['a', 1, 2, 3, 'b'], getAscii)); // [97, 49, 50, 51, 98]

Con estos ejemplos continuamos aprendiendo la potencia de las funciones de orden superior, ya que pasamos como argumento una función y esta se ejecuta dentro sin importar la lógica de la función que le pasamos.

La otra forma que tenemos de considerar a una función como una función de orden superior es que esta nos devuelva una función.

Este concepto también es conocido como clausura (closure), que no es mas que una función que nos permite acceder desde una función interior al ámbito de una función exterior.

Vamos a ver algún ejemplo para comprender este concepto.

function api(url) {
    const iUrl = url;
    return async function setId(id) {
         return await (await fetch(`${iUrl}/${id}`)).json();
    }
}

// Devolvemos una función y la almacenamos en la variable "post"
const post = api('https://jsonplaceholder.typicode.com/posts');

console.log(post); /* return async function setId(id) { return await (await fetch(`${iUrl}/${id}`)).json(); } */
// Ahora en la variable "post" tenemos la función setId (que podría ser anónima)
post(1).then(item => {
    console.log('DATA:', item);
}).catch(err => {
    console.error('ERROR:', err);
});

post(2).then(item => {
    console.log('DATA:', item);
}).catch(err => {
    console.error('ERROR:', err);
});

post(3).then(item => {
    console.log('DATA:', item);
}).catch(err => {
    console.error('ERROR:', err);
});

Podemos comprobar que en la función api estamos «guardando» la url donde queremos hacer la llamada.

A continuación retornamos una función que será la encargada de devolvernos el resultado y que además la respuesta cambiará dependiendo del argumento de entrada.

Como hemos podido comprobar las funciones de orden superior tienen muchas aplicaciones y una potencia tremenda para separar y aislar toda la lógica de nuestras aplicaciones.