Funções de ordem superior em JavaScript

Uma função de ordem superior é uma função que recebe outra função como parâmetro ou retorna uma função como saída. Funções de ordem superior são amplamente utilizadas e implementadas em JavaScript para melhorar a legibilidade e flexibilidade do código. A integração de funções de ordem superior em sua lógica de código evita redundância de código, economizando tempo e recursos.

Este tutorial apresentará funções de ordem superior, como usá-las e seus benefícios.

Como passar uma função como argumento para outra função.

Passar funções como argumentos para outras funções é uma das maneiras de personalizar o comportamento das funções. Ele permite passar diferentes funções como parâmetros para uma única função, tornando seu código mais limpo e reutilizável. Vejamos como podemos fazer isso.

Exemplo 1

Considere o calculate() função, que nos ajuda a realizar diversos cálculos matemáticos. São necessários dois números, aeb, e uma função de operação como argumentos. Definimos então as diferentes funções matemáticas, ou seja, adde subtract.

Usamos então o calculate() funcionar com qualquer uma das funções matemáticas e fornecer os números inteiros nos quais as operações matemáticas serão realizadas.

1
function calculate(a, b, operation) {
2
    return operation(a,b);
3
  }
4
  
5
 
6
  function add(a, b) {
7
    return a + b;
8
  }
9
  
10
  function subtract(a, b) {
11
    return a - b;
12
  }
13
  
14

15
console.log(calculate(10, 5, add)); //output // 15

16
console.log(calculate(10, 5, subtract)); //output //5

Como você pode ver acima, ao separar as diferentes operações, nosso código pode ser facilmente extensível sem alterar o calculate () função.

Exemplo 2

Vejamos outro exemplo. Suponha que você tenha o conjunto de nomes mostrado abaixo;

1
const names = ['Ann','Alex', 'Barman', 'zen','liz', 'Christopher', 'Isabella']

Então, suponha que você tenha a tarefa de filtrar as pessoas cujos nomes têm três caracteres ou menos; você provavelmente pensaria em algo assim:

1
function shortNames(namesArr){
2
    const result = []
3
    for(i=0; i< namesArr.length; i++){
4
        if (namesArr[i].length <= 3){
5
            result.push(namesArr[i])
6
            
7
        }
8
    }
9
    return result
10
}
11

12
console.log(shortNames(names)) //output //[ 'Ann', 'zen', 'Liz' ]

Aqui, criamos uma função shortNames, que usa uma matriz de nomes como parâmetro. Então, definimos um array vazio chamado result. Então, criamos um for loop, que percorre cada elemento da matriz e verifica seu comprimento. Se o comprimento de um elemento for menor ou igual a 3 caracteres, o elemento será considerado um nome abreviado e enviado para a matriz de resultados. Finalmente, retornamos o novo array contendo os nomes curtos filtrados.

Suponha que também precisamos obter todas as pessoas com nomes longos, ou seja, nomes com oito ou mais caracteres; nossa função seria semelhante à shortNames() função

1
function LongNames(namesArr){
2
    const result = []
3
    for(i=0; i< namesArr.length; i++){
4
        if (namesArr[i].length >= 8){
5
            result.push(namesArr[i]) 
6
            
7
        }
8
    }
9
    return result
10
}
11
console.log(LongNames(names)); //ouput // [ 'Christopher', 'Isabella' ]

O LongNames e shortNames ambas as funções executam tarefas semelhantes, como:

  • percorrendo a matriz de nomes
  • filtrando cada nome na matriz com base na condição especificada
  • empurrando elementos que satisfazem a condição para um novo array

No entanto, podemos encurtar nosso código e evitar tarefas repetitivas criando uma função comum. Como não precisamos de toda a lógica em nossas duas funções acima, podemos reescrevê-las conforme mostrado abaixo.

1
function isShortName(name, length) {
2
    return name.length <= length;
3
}
4

5
function isLongName(name, length) {
6
    return name.length >= length;
7
}

Aqui definimos nossas funções isShortName e isLongNameque aceita dois argumentos: nome e comprimento. isShortName irá verificar se o nome fornecido é menor ou igual ao comprimento especificado. Ele retorna true se o nome fornecido satisfizer a condição.

IsLongName() faz algo semelhante, mas retorna true se o nome fornecido for maior ou igual ao comprimento fornecido.

A seguir, criaremos um filterNames função para filtrar nomes com base em diferentes condições. O filterNames função receberá três argumentos:

  • matriz de nomes.
  • A função de retorno de chamada (pode ser IsLongName ou isShortName).
  • A condição de comprimento usada para filtrar os nomes.
1
function filterNames(namesArr, conditionFn, length) {
2
    const result = [];
3
    for (let i = 0; i < namesArr.length; i++) {
4
        if (conditionFn(namesArr[i], length)) {
5
            result.push(namesArr[i]);
6
        }
7
    }
8
    return result;
9
}

Então agora, se decidirmos usar o filterNames() com qualquer uma das funções de retorno de chamada, obteremos a mesma saída.

1
console.log(filterNames(names, isShortName, 3)); // [ 'Ann', 'zen', 'Liz' ]

2
console.log(filterNames(names, isLongName, 8));  //[ 'Christopher', 'Isabella' ]

Exemplos de funções de ordem superior

Funções de ordem superior são comumente usadas para mapear, filtrar e reduzir matrizes. As funções de ordem superior mais comumente usadas incluem:

  • filtro()
  • mapa()
  • reduzir()

Usando o método filter()

Como o nome sugere, o filter() O método filtra elementos em uma matriz com base na condição especificada. Quando aplicado a uma matriz, o filter() O método criará outro array com apenas os elementos do array original que satisfazem a condição na função.

Considere a matriz abaixo, que consiste nos nomes e salários de alguns funcionários.

1
const funcionários = [
2
    {name: "Alice",salary: 25000 },
3
    {name: "Bob",salary: 30000},
4
    {name: "Charlie",salary: 28000},
5
    {name: "Cate",salary: 100000,},
6
    {name: "Mike",salary: 120000,},
7
    {name: "Lucy",salary: 55000,},
8
    {name: "Liam",salary: 70000,},
9
]

Suponha que queiramos filtrar os funcionários que ganham mais de 70.000. Uma maneira de fazer isso seria usar um for fazer um loop, fazer um loop sobre cada elemento e, a cada iteração, enviar o funcionário que satisfaz nossa condição para um novo array, conforme mostrado abaixo.

1
const filteredEmployees = []
2
for(i =0 ;i 
3
    if(employees[i].salary >=70000 ){
4
        filteredEmployees.push(employees[i])
5
 }}
6
 
7
 console.log(filteredEmployees);

Mesmo que a função funcione conforme o esperado, existem maneiras melhores de implementar a solução. O filter () método é uma excelente solução para o nosso problema. Sua sintaxe é assim;

1
const newArray = array.filter(callbackFn,thisArg)

Onde callbackFn é a função para filtrar elementos. O callbackFn leva três argumentos opcionais: element, indexe array. thisArg é opcional.

Vamos primeiro definir o callbackFn, que receberá um objeto funcionário e verificará se o valor na propriedade salário é superior a 70.000.

1
function checkSalary(employee){
2
    return employee.salary >= 70000
3
}

A seguir, vamos aplicar o filter() método para o nosso callbackFxn e atribuí-lo ao filtredArray.

1
const filteredArray = employees.filter(checkSalary);
2
console.log(filteredArray)

Nossa saída ficará assim:

1
[
2
  { name: 'Cate', salary: 100000 },
3
  { name: 'Mike', salary: 120000 },
4
  { name: 'Liam', salary: 70000 }
5
]

Usando o método Map()

O map() método é outra função de ordem superior que cria um novo array aplicando uma função de retorno de chamada a cada elemento do array original.

A sintaxe é semelhante a esta:

1
const newArray = originalArray.map(callbackFn, thisArg);

onde o callbackFn recebe os seguintes parâmetros,

  • currentValue - o elemento atual sendo processado
  • index - o índice do elemento atual que está sendo processado
  • array -a matriz original

thisArg é opcional.

Dada a matriz de alunos abaixo, que contém os nomes e as notas dos alunos para diferentes disciplinas e notas gerais, queremos extrair apenas os nomes e as notas gerais da matriz.

1
const estudantes = [
2
    {
3
        names: "Alice Bob",Math: 85,Science: 92,History: 78,English: 88,Art: 95,
4
        grade:87.6
5
    },
6
    {
7
        names: "Michael Smith",Math: 76,Science: 89,History: 92,English: 80,
8
        Art: 91,
9
        grade:85.6
10
    },
11
    {
12
        names: "William Brown",Math: 70,Science: 78,History: 75,English: 88,Art: 79,
13
        grade:76
14
    },
15
    {
16
        names: "Julia Lee", Math: 52, Science: 63, History: 76, English: 87,
17
        Art: 94,
18
        grade:74.2
19
    },
20
    {
21
        names:"George Harrison",Math: 88,Science: 77,History: 50,English: 84,
22
        Art: 71,
23
        grade:74
24
    },
25
];

Podemos usar o map() método para recuperar os nomes dos alunos e notas gerais. Primeiro, vamos criar a função de retorno de chamada, que recebe um aluno como argumento e extrai o nome do aluno e a nota geral.

1
function gradeOnly(student){
2
   return ({names:student.names, grade: student.grade})
3
}

Nossa função de retorno de chamada pegará um objeto aluno como argumento e retornará um novo objeto contendo apenas os nomes e as propriedades das notas.

A seguir, usaremos o método map() para criar um novo array aplicando o método gradeOnly() para cada aluno na matriz de alunos. O map() método irá iterar através de cada elemento da matriz do aluno e aplicar o gradeOnly() função.

1
const studentsData = students.map(gradeOnly)
2
console.log(studentsData)

Nossa saída será:

1
[
2
  { names: 'Alice Bob', grade: 87.6 },
3
  { names: 'Michael Smith', grade: 85.6 },
4
  { names: 'William Brown', grade: 76 },
5
  { names: 'Julia Lee', grade: 74.2 },
6
  { names: 'George Harrison', grade: 74 }
7
]

Usando funções de seta, podemos simplificar esta expressão da seguinte forma:

1
const studentsData = students.map(
2
    student=> ({names:student.names, grade: student.grade}))
3
console.log(studentsData)

Usando o método Array.reduce()

Como o nome sugere, o reduce() O método pega um array e o reduz a um único valor. A sintaxe do método de redução é semelhante a esta.

1
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

onde

  • O total será o resultado
  • o currentValue será o elemento atual durante o processo de iteração
  • O valor inicial será 0
  • currentIndex e arr são opcionais

Suponha que você queira descobrir a soma dos números na matriz de números abaixo usando o reduce() método:

1
numbers = [10,20,30,40]

Vamos começar definindo a função de retorno de chamada que receberá o total e o número como argumentos. A função de retorno de chamada retornará o resultado da adição de cada número em nosso array original ao total.

1
function addNumbers(total,number){
2
    return total+=number
3
}

A seguir, aplique o reduce() método para a matriz de números e use o addNumbers como a função de retorno de chamada. Cada elemento na matriz de números é aplicado à função de retorno de chamada para cada iteração.

1
const cumulativeTotal =numbers.reduce(addNumbers);
2
console.log(cumulativeTotal); //output //100

A saída será 100, conforme esperado. Se não definirmos um valor inicial, o primeiro elemento será considerado o valor inicial e a saída ainda será a mesma.

1
numbers = [10,20,30,40]
2
numbers.reduce(function(total, number){
3
    return total+number
4
})

Podemos encurtar ainda mais nossa expressão usando funções de seta da seguinte forma:

1
const cumulativeTotal = numbers.reduce((total,number) => total+=number)
2
console.log(cumulativeTotal); //output //100

Benefícios das funções de ordem superior

  • Funções de ordem superior abstraem a lógica subjacente necessária para a execução de tarefas. Por exemplo, quando usamos o reduce() método, abstraímos a lógica subjacente de iterar cada elemento, somando-o ao total e retornando o resultado. Não precisamos escrever explicitamente a lógica de iteração e acumulação; a função de redução cuidou disso para nós.
  • A utilização de funções de ordem superior melhora a legibilidade e a manutenção do código em comparação com a implementação da mesma funcionalidade com loops.
  • Funções de ordem superior também tornam seu código reutilizável.

Aprimore seu jogo JS com Tuts+

Conclusão

Este tutorial apresentou funções de ordem superior e ofereceu exemplos práticos e cenários onde elas podem ser aplicadas à programação JavaScript. Incorporar funções de ordem superior em suas práticas de desenvolvimento pode aprimorar significativamente suas habilidades como desenvolvedor JavaScript.

[ad_2]

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *