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 UnsplashAprendendo 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'); }
Para mostrar que funções em JavaScript são objetos, podemos fazer algo assim:
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; }
Eles também podem ser transmitidos. Por exemplo:
const foo = square;
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(); } }
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.mapO 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. 1Suponha 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); }
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. 2Digamos 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); }
Usando a função de
map
ordem superior:
const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year);
Array.prototype.filterO 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. 1Imagine 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.reduceO 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:
- função de retorno de chamada a ser processada;
- 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. 1Suponha 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; });
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);
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]; }
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; });
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. :)