<h2>O que são Higher-Order Functions?</h2>
<p>Higher-Order Functions (HOF) são funções que recebem outras funções como argumentos ou retornam funções como resultado. Elas são fundamentais na programação funcional e permitem escrever código mais reutilizável, expressivo e modular. Em JavaScript, como tudo é um objeto — inclusive funções — trabalhar com HOF é natural e poderoso.</p>
<p>O grande benefício é a abstração: em vez de escrever loops repetitivos, você descreve <em>o que</em> quer fazer com seus dados. Isso torna o código mais legível e menos propenso a erros. Vamos explorar as três HOFs mais importantes: <code>map</code>, <code>filter</code> e <code>reduce</code>.</p>
<h2>Map, Filter e Reduce na Prática</h2>
<h3>Map: Transformar Dados</h3>
<p><code>Map</code> aplica uma função a cada elemento de um array e retorna um novo array com os resultados. Use-o quando quiser <strong>transformar</strong> todos os itens de forma igual.</p>
<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5];
const dobrados = numeros.map(n => n * 2);
console.log(dobrados); // [2, 4, 6, 8, 10]
// Exemplo real: converter objetos de uma API
const usuarios = [
{ id: 1, nome: "Ana" },
{ id: 2, nome: "Bruno" }
];
const nomes = usuarios.map(u => u.nome);
console.log(nomes); // ["Ana", "Bruno"]</code></pre>
<h3>Filter: Selecionar Dados</h3>
<p><code>Filter</code> cria um novo array contendo apenas os elementos que passam em um teste. Use-o para <strong>remover ou selecionar</strong> itens baseado em uma condição.</p>
<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5, 6];
const pares = numeros.filter(n => n % 2 === 0);
console.log(pares); // [2, 4, 6]
// Exemplo real: listar apenas usuários ativos
const usuarios = [
{ id: 1, nome: "Ana", ativo: true },
{ id: 2, nome: "Bruno", ativo: false },
{ id: 3, nome: "Carlos", ativo: true }
];
const ativos = usuarios.filter(u => u.ativo);
console.log(ativos); // Ana e Carlos</code></pre>
<h3>Reduce: Agregar Dados</h3>
<p><code>Reduce</code> acumula valores em um único resultado, passando por cada elemento. Use-o para <strong>sumarizar</strong> dados: somas, contagens, agregações ou transformações complexas.</p>
<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5];
const soma = numeros.reduce((acumulador, atual) => acumulador + atual, 0);
console.log(soma); // 15
// Exemplo real: contar ocorrências de palavras
const palavras = ["gato", "cão", "gato", "pato", "cão", "cão"];
const contagem = palavras.reduce((acc, palavra) => {
acc[palavra] = (acc[palavra] || 0) + 1;
return acc;
}, {});
console.log(contagem); // { gato: 2, cão: 3, pato: 1 }</code></pre>
<h2>Composição de Higher-Order Functions</h2>
<p>Composição é combinar múltiplas funções pequenas para resolver problemas complexos. A beleza é que <code>map</code>, <code>filter</code> e <code>reduce</code> retornam arrays (ou valores), permitindo encadeamento natural.</p>
<pre><code class="language-javascript">const usuarios = [
{ id: 1, nome: "Ana", salario: 3000, ativo: true },
{ id: 2, nome: "Bruno", salario: 2500, ativo: false },
{ id: 3, nome: "Carlos", salario: 4000, ativo: true }
];
// Problema: somar salários apenas de usuários ativos
const totalAtivos = usuarios
.filter(u => u.ativo)
.map(u => u.salario)
.reduce((acc, sal) => acc + sal, 0);
console.log(totalAtivos); // 7000 (Ana + Carlos)</code></pre>
<p>Esse padrão é extremamente legível: filtro → extraio salários → somo. Para problemas ainda mais complexos, crie funções compostas reutilizáveis:</p>
<pre><code class="language-javascript">// Criar predicados e transformadores reutilizáveis
const ehAtivo = u => u.ativo;
const extrairSalario = u => u.salario;
const somar = (acc, val) => acc + val;
// Aplicar em qualquer contexto
const totalAtivos = usuarios
.filter(ehAtivo)
.map(extrairSalario)
.reduce(somar, 0);
// Outra composição: média salarial
const quantidadeAtivos = usuarios.filter(ehAtivo).length;
const mediaAtivos = totalAtivos / quantidadeAtivos;
console.log(mediaAtivos); // 3500</code></pre>
<h2>Criando Funções Compostas Avançadas</h2>
<h3>Função Compose Genérica</h3>
<p>Uma função <code>compose</code> recebe múltiplas funções e as aplica em sequência. Isso é programação funcional pura:</p>
<pre><code class="language-javascript">// Compose: aplica funções da direita para esquerda
const compose = (...funcs) => valor =>
funcs.reduceRight((acc, func) => func(acc), valor);
// Funções básicas
const adicionar10 = x => x + 10;
const multiplicarPor2 = x => x * 2;
const dividirPor5 = x => x / 5;
// Compor: (((5 * 2) + 10) / 5)
const pipeline = compose(dividirPor5, adicionar10, multiplicarPor2);
console.log(pipeline(5)); // 4
// Pipe: aplica da esquerda para direita (mais intuitivo)
const pipe = (...funcs) => valor =>
funcs.reduce((acc, func) => func(acc), valor);
const processamento = pipe(multiplicarPor2, adicionar10, dividirPor5);
console.log(processamento(5)); // 4</code></pre>
<h3>Exemplo Real: Processamento de Dados</h3>
<pre><code class="language-javascript">const dados = [
{ nome: "Alice", idade: 25, ativo: true },
{ nome: "Bob", idade: 17, ativo: false },
{ nome: "Carol", idade: 30, ativo: true }
];
// Predicados e transformadores específicos
const maioresDeIdade = p => p.idade >= 18;
const ehAtivo = p => p.ativo;
const extrairNome = p => p.nome;
// Composição prática
const nomesMaioresEAtivos = dados
.filter(maioresDeIdade)
.filter(ehAtivo)
.map(extrairNome);
console.log(nomesMaioresEAtivos); // ["Alice", "Carol"]
// Ou com um único filter (otimizado):
const nomesMaioresEAtivos2 = dados
.filter(p => maioresDeIdade(p) && ehAtivo(p))
.map(extrairNome);</code></pre>
<h2>Conclusão</h2>
<p>Higher-Order Functions são pilares da programação moderna em JavaScript. Ao dominar <code>map</code> para transformações, <code>filter</code> para seleções e <code>reduce</code> para agregações, você escreve código declarativo e robusto. Composição de HOFs permite resolver problemas complexos de forma elegante e legível — é o caminho para se tornar um desenvolvedor mais eficiente. Pratique combinando essas funções em seus projetos reais e perceba como seu código fica mais profissional e manutenível.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/map" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.map()</a></li>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/filter" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.filter()</a></li>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.reduce()</a></li>
<li><a href="https://eloquentjavascript.net/05_higher_order.html" target="_blank" rel="noopener noreferrer">Eloquent JavaScript - Capítulo sobre Funções de Ordem Superior</a></li>
<li><a href="https://github.com/getify/You-Dont-Know-JS" target="_blank" rel="noopener noreferrer">You Don't Know JS Yet - Functional Programming</a></li>
</ul>