DEV Community

Cover image for O que são funções de ordem superior em Javascript?
Pedro Tashima
Pedro Tashima

Posted on

O que são funções de ordem superior em Javascript?

Antes de dar uma definição formal, vamos entender onde elas podem ser úteis e por que usá-las.
Em um certo sistema, diversas operações de divisão de arrays são necessárias.
Essa é uma das maneiras de implementar essas operações:

const copyArrayAndDivideBy2 = (arr) => {
 const result = []
  for(let i = 0; i < arr.length; i++) {
   result.push(arr[i] / 2)
 }
  return result
}

const copyArrayAndDivideBy3 = (arr) => {
 const result = []
  for(let i = 0; i < arr.length; i++) {
   result.push(arr[i] / 3)
 }
  return result
}
Enter fullscreen mode Exit fullscreen mode

Obviamente essa solução é péssima, praticamente todo o código é repetido, bugs conseguem se esconder facilmente e se caso a lógica mude, alguém vai precisar encontrar todas as funções e alterar uma por uma. Existem várias soluções melhores pra esse problema e uma delas é utilizar funções de ordem superior, que é o que vamos fazer a seguir.

O que são funções de ordem superior?

Uma função de ordem superior, ou higher order function (HOF), como vamos chama-la, é uma função que recebe como argumento, ou retorna uma função. Isso é possível porque em Javascript, funções são entidades de primeira classe, ou seja, é possível passar elas como argumentos para uma outra função.

Mas por que HOFs são importantes? Elas são ótimas ferramentas para evitar repetição desnecessária e seguir princípios como o DRY e KISS.

Como usar em Javascript

Vamos continuar o exemplo anterior, refatorando aquelas funções para uma HOF.

Aqui, toda a parte de copiar o array e iterar sobre ele é separada da lógica, que vai ser passada como argumento quando essa função for chamada.

const copyArrayAndManipulate = (arr, instructions) => {
// o parâmetro `instructions` normalmente é chamado de `callback`
// ele deve ser uma funcao que contém toda a lógica de manipulação
// do elemento, antes dele ser copiado para o resultado.
    const result = []
    for(let i = 0; i < arr.length; i++) {
        result.push(instructions(arr[i])
    }
    return result
}
Enter fullscreen mode Exit fullscreen mode

Agora conseguimos utilizar essa função para fazer o mesmo que antes, mas evitando repetição de código.

const divideBy2 = (input) => input / 2
const arrayDividedBy2 = copyArrayAndManipulate([2, 4, 6], divideBy2) // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Simplificando ainda mais a implementação, podemos refatorar ela novamente:

const arrayDividedBy2 = copyArrayAndManipulate(
    [2, 4, 6], 
    (input) => input / 2
) // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Espero que agora tenha ficado muito mais claro onde usar essas funções

HOFs na biblioteca padrão do Javascript

A função copyArrayAndManipulate é muito parecida com uma padrão da linguagem, a Array.forEach e isso não é coincidência, HOFs são utilizadas múltiplas vezes nas funções padrões do JS.

Podemos implementar uma versão mais simples do Array.forEach com os conceitos que aprendemos nesse artigo, que funciona de uma forma muito similar a original.

// recebe como parâmetro um array para iterar 
// e uma função com a lógica a ser executada
const iterateOver = (array, callback) => {
    let i = 0, len = array.length
    while(i < len) {
        const value = array[i]
        // executar a função passada por quem está chamando a função
        // e passar como argumento o elemento atual do array e o índice dele
        callback(value, i)
        i++ 
    }
}
// chamando a função definida anteriormente e passando uma função
// de callback que imprime os elementos do array junto com o índice deles
iterateOver([1, 2, 3], (a, i) => {
    console.log(`elemento: ${a}, índice: ${i}`)
})
/* output
> elemento: 1, índice: 0
> elemento: 2, índice: 1
> elemento: 3, índice: 2
*/
Enter fullscreen mode Exit fullscreen mode

Conclusão

Funções de ordem superior são uma ferramenta extremamente útil para o dia a dia, elas são utilizadas em diversos lugares nas funções embutidas no JS e em outras bibliotecas, porém, o conceito pode ser um pouco difícil de se entender, se algo não ficou claro, por favor entre em contato comigo!

Referências

https://eloquentjavascript.net/05_higher_order.html

https://frontendmasters.com/courses/javascript-hard-parts-v2/

https://www.developintelligence.com/blog/2016/10/javascript-functions-as-first-class-objects/#:~:text=Basically%2C first-class citizenship simply,be assigned key%3A value pairs.

https://medium.com/@angelorubin/javascript-first-class-function-funções-de-primeira-classe-7ebf63d2c83a

http://www.macoratti.net/16/04/net_dry1.htm#:~:text=O princípio DRY%2C 'Não se,e definitiva dentro do sistema."

Discussion (0)