Funções de ordem superior em JavaScript: o que é?

Apresentamos uma tradução de um artigo de Sukhjinder Arora publicado em Bits and Pieces . Descubra sob o gato sobre funções de ordem superior em JavaScript e algumas outras funções que são incorporadas a essa linguagem.


Foto de NESA por Makers de Unsplash

Aprendendo a programação JavaScript, você provavelmente se deparou com o conceito de funções de ordem superior . Embora esse conceito possa parecer intimidador, na verdade não é tão complicado.

Graças à capacidade de trabalhar com funções de ordem superior, o JavaScript é adequado para programação funcional.

Funções de ordem superior são comuns em JavaScript. Se você trabalhou com ele por um tempo, é muito provável que você tenha usado essas funções sem nem mesmo perceber.

Para obter uma imagem completa das funções de ordem superior, primeiro você precisa entender o que são programação funcional e funções de primeira classe .

Dica : reutilizar funções JavaScript geralmente leva a duplicatas. Para evitar isso, use Bit (GitHub) . Você pode facilmente encontrar novos recursos, compartilhá-los e reaplicá-los com alterações mínimas de gerenciamento. Experimente, não seja tímido.

O que é programação funcional


Sem entrar em detalhes, programação funcional é a programação na qual algumas funções são passadas como argumentos para outras funções e retornam terceiros como valores. Na programação funcional, pensamos e operamos com funções.

A programação funcional é feita em linguagens como JavaScript, Haskell, Clojure, Scala e Erlang.

O que são recursos de primeira classe


Ao aprender a trabalhar com JavaScript, você provavelmente já ouviu falar que, para ele, as funções são cidadãos de primeira classe. O fato é que no JavaScript, como em qualquer outra linguagem de programação funcional, as funções são objetos.

Especificamente para JavaScript, funções são objetos de um tipo especial (objetos de Function ou functores). Por exemplo:

 function greeting() { console.log('Hello World'); } // Invoking the function greeting(); // prints 'Hello World' 

Para mostrar que funções em JavaScript são objetos, podemos fazer algo assim:

 // We can add properties to functions like we do with objects greeting.lang = 'English'; // Prints 'English' console.log(greeting.lang); 

Nota: embora o acima funcione bem no JavaScript, você não deve abusar dele. Você não pode atribuir propriedades aleatórias aos functores - é melhor usar objetos regulares.

Em JavaScript, tudo o que você pode fazer com outras entidades, como um objeto, uma sequência ou um número, se aplica a funções. Eles podem ser passados, inclusive como argumentos para outras funções (chamadas de funções de retorno de chamada ou funções de retorno de chamada), atribuí-los a variáveis ​​e assim por diante. É por isso que as funções JavaScript são chamadas de funções de primeira classe.

Atribuindo funções a variáveis


JavaScript permite atribuir funções a variáveis. Por exemplo:

 const square = function(x) { return x * x; } // prints 25 square(5); 

Eles também podem ser transmitidos. Por exemplo:

 const foo = square; // prints 36 foo(6); 

Passando funções como argumentos


Podemos passar funções como argumentos para outras funções. Por exemplo:

 function formalGreeting() { console.log("How are you?"); } function casualGreeting() { console.log("What's up?"); } function greet(type, greetFormal, greetCasual) { if(type === 'formal') { greetFormal(); } else if(type === 'casual') { greetCasual(); } } // prints 'What's up?' greet('casual', formalGreeting, casualGreeting); 

Portanto, agora que sabemos o que são funções de primeira classe, passemos a funções de ordem superior em JavaScript.

Funções de ordem superior


Funções de ordem superior são funções que funcionam com outras funções, assumindo uma função como argumento ou retornando uma função como resultado.

Exemplos de funções de ordem superior que já estão incorporadas ao idioma são Array.prototype.map , Array.prototype.filter e Array.prototype.reduce .

Funções de ordem superior em ação


Vamos examinar alguns exemplos de funções internas de ordem superior e compará-los com soluções em que funções de ordem superior não são usadas.

Array.prototype.map
O método map() cria uma nova matriz com o resultado da chamada da função passada para cada elemento da matriz inicial. O método map() pega cada valor da função de retorno de chamada e cria uma nova matriz usando esses valores.

A função de retorno de chamada passada para o método map() leva três argumentos: element , index e array .

Considere isso com alguns exemplos.

Exemplo No. 1
Suponha que tenhamos uma matriz de números e a partir dela queremos criar uma nova matriz na qual cada número da matriz inicial seja duplicado. Como podemos resolver esse problema com e sem uma função de ordem superior?

Sem uma função de ordem superior:

 const arr1 = [1, 2, 3]; const arr2 = []; for(let i = 0; i < arr1.length; i++) { arr2.push(arr1[i] * 2); } // prints [ 2, 4, 6 ] console.log(arr2); 

Usando a função de map ordem superior:

 const arr1 = [1, 2, 3]; const arr2 = arr1.map(function(item) { return item * 2; }); console.log(arr2); 

O código pode ser reduzido ainda mais usando a função de seta.

 const arr1 = [1, 2, 3]; const arr2 = arr1.map(item => item * 2); console.log(arr2); 

Exemplo No. 2
Digamos que temos uma matriz que contém os anos de nascimento de várias pessoas e, a partir dela, queremos criar uma nova matriz na qual suas idades serão.

Sem uma função de ordem superior:

 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = []; for(let i = 0; i < birthYear.length; i++) { let age = 2018 - birthYear[i]; ages.push(age); } // prints [ 43, 21, 16, 23, 33 ] console.log(ages); 

Usando a função de map ordem superior:

 const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year); // prints [ 43, 21, 16, 23, 33 ] console.log(ages); 

Array.prototype.filter
O método filter() cria uma nova matriz com todos os elementos aprovados no teste especificado na função aprovada. A função de retorno de chamada passada para filter() leva três argumentos: element , index e array .

Considere isso com alguns exemplos.

Exemplo No. 1
Imagine que temos uma matriz contendo objetos com as propriedades "nome" e "idade". A partir disso, queremos criar uma nova matriz na qual apenas os adultos (a partir dos dezoito anos ou mais) serão indicados.

Sem uma função de ordem superior:

 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = []; for(let i = 0; i < persons.length; i++) { if(persons[i].age >= 18) { fullAge.push(persons[i]); } } console.log(fullAge); 

Usando a função de filter ordem superior:

 const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = persons.filter(person => person.age >= 18); console.log(fullAge); 

Array.prototype.reduce
O método reduce aplica uma função a cada valor da matriz, reduzindo-o a um único valor. O método reduzir usa dois argumentos:
  1. função de retorno de chamada a ser processada;
  2. parâmetro opcional initialValue (primeiro argumento na primeira chamada de função).

A função de retorno de chamada recebe quatro argumentos: accumulator , valor currentValue , currentValue , currentValue .

Se o parâmetro initialValue foi passado, o argumento accumulator será igual ao argumento initialValue e o argumento currentValue o primeiro elemento da matriz.

Se o parâmetro initialValue não foi passado, o argumento accumulator será igual ao primeiro elemento da matriz e o segundo elemento da matriz será considerado como argumento currentValue .

Exemplo No. 1
Suponha que precisamos encontrar a soma dos números em uma matriz.

Usando uma função de ordem superior, reduce :

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }); // prints 25 console.log(sum); 

Sempre que uma função de retorno de chamada é aplicada a cada valor da matriz, o argumento accumulator salva o resultado da ação anterior retornada pela função e currentValue assume o próximo valor da matriz. Após a conclusão, o resultado é armazenado na variável sum .

Além disso, podemos passar para esta função o valor inicial:

 const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 10); // prints 35 console.log(sum); 

Sem uma função de ordem superior:

 const arr = [5, 7, 1, 8, 4]; let sum = 0; for(let i = 0; i < arr.length; i++) { sum = sum + arr[i]; } // prints 25 console.log(sum); 

Como você pode ver, com a ajuda de uma função de ordem superior, o código pode ser melhor, mais curto e mais amplo.

Crie sua própria função de ordem superior


Até este ponto, consideramos várias funções de ordem superior incorporadas à linguagem. É hora de criar sua própria função de ordem superior.

Imagine que o JavaScript não teria seu próprio método de map . Poderíamos construí-lo nós mesmos, criando assim nossa própria função de uma ordem superior.

Digamos que temos uma matriz de seqüências de caracteres, e com isso queremos criar uma matriz de integrais na qual cada elemento represente o comprimento da sequência da matriz inicial.

 const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C']; function mapForEach(arr, fn) { const newArray = []; for(let i = 0; i < arr.length; i++) { newArray.push( fn(arr[i]) ); } return newArray; } const lenArray = mapForEach(strArray, function(item) { return item.length; }); // prints [ 10, 6, 3, 4, 1 ] console.log(lenArray); 

No exemplo acima, criamos uma função de ordem superior mapForEach , que usa uma matriz e uma função de retorno de chamada fn como argumentos. Essa função é aplicada ciclicamente a cada elemento da matriz e chama a função de retorno de chamada fn como parte da newArray.push função newArray.push em cada iteração.

A função de retorno de chamada fn pega o elemento atual da matriz inicial e retorna o valor de comprimento desse elemento, que é armazenado dentro do novo newArray . Após a conclusão da iteração, a matriz newArray retornada como resultado e atribuída à matriz lenArray .

Conclusão


Aprendemos o que são funções de ordem superior e examinamos algumas das funções incorporadas à linguagem. Também aprendemos como criar suas próprias funções de ordem superior.

Em resumo, as funções de ordem superior funcionam como funções regulares, mas têm a capacidade adicional de receber outras funções como argumento e retorná-las como resultado.

Isso, de fato, é tudo. Se você achou este artigo útil, também pode me seguir no Medium e no Twitter . Sinta-se livre para comentar se você tiver alguma dúvida! Ficarei feliz em ajudar. :)

Source: https://habr.com/ru/post/pt428612/


All Articles