Funções e arrow functions
Por que existir
Sem função, o mesmo cálculo aparece em quatro lugares: e quando a regra muda, você precisa lembrar dos quatro.
function precoFormatado(centavos) {
return (centavos / 100).toLocaleString("pt-BR", {
style: "currency",
currency: "BRL",
});
}
console.log(precoFormatado(1250)); // → R$ 12,50
console.log(precoFormatado(87500)); // → R$ 875,00
Um lugar para mudar, um nome que explica o que acontece.
Três formas de escrever
// 1. Declaração
function somar(a, b) {
return a + b;
}
// 2. Expressão
const somar2 = function (a, b) {
return a + b;
};
// 3. Arrow function
const somar3 = (a, b) => a + b;
A diferença prática é o hoisting: a declaração é içada para o topo do arquivo e pode ser chamada antes de aparecer no código. As outras duas, não.
console.log(somar(2, 3)); // → 5, funciona
console.log(somar3(2, 3)); // ReferenceError
function somar(a, b) {
return a + b;
}
const somar3 = (a, b) => a + b;
Arrow function
// Corpo com chaves: precisa de return
const dobro = (n) => {
return n * 2;
};
// Sem chaves: retorno implícito
const dobro2 = (n) => n * 2;
// Um parâmetro: parênteses opcionais
const dobro3 = (n) => n * 2;
// Nenhum parâmetro: parênteses obrigatórios
const agora = () => new Date();
// Devolver objeto: envolva em parênteses
const criar = (nome) => ({ nome, criadoEm: new Date() });
O último merece nota: sem os parênteses, o { seria lido como início do corpo
da função, e não como um objeto.
A forma curta é o que torna map e filter legíveis:
const precos = [1250, 2500, 800];
precos.map(function (p) {
return p / 100;
});
precos.map((p) => p / 100); // o mesmo, mais direto
return
function classificar(idade) {
if (idade < 12) return "criança";
if (idade < 18) return "adolescente";
if (idade < 60) return "adulto";
return "idoso";
}
return encerra a função na hora. Nada depois dele roda.
function semRetorno(a, b) {
const soma = a + b; // calculou e jogou fora
}
console.log(semRetorno(2, 3)); // → undefined
Escopo
function calcular() {
const interna = 10;
console.log(interna); // → 10
}
calcular();
console.log(interna); // ReferenceError
O que se declara dentro fica dentro. E isso é uma qualidade: cada função tem seu próprio espaço, e nomes não colidem entre elas.
const e let respeitam também o bloco:
if (true) {
const dentro = "só aqui";
}
console.log(dentro); // ReferenceError
Funções que se explicam
// O nome não diz nada
function calc(a, b) {
return a * b * 0.1;
}
// O nome e os parâmetros contam a história
function descontoDeDezPorCento(precoEmCentavos, quantidade) {
return Math.round(precoEmCentavos * quantidade * 0.1);
}
Verbo no começo; calcular, formatar, validar, buscar -, ou e/tem
para as que respondem sim ou não: ehMaiorDeIdade, temVaga.
A função pura
// Depende de coisa de fora e mexe em coisa de fora
let total = 0;
function adicionar(valor) {
total += valor;
}
// Pura: mesma entrada, mesma saída, nada tocado por fora
function somar(total, valor) {
return total + valor;
}
A segunda dá para testar com uma linha, sem preparar nada. A primeira exige saber o estado do mundo antes de chamar: e o resultado depende de quem chamou antes.
Um conjunto de funções
const PRECO_POR_KG_EM_CENTAVOS = {
farinha: 1250,
acai: 2500,
tucuma: 800,
};
const formatarPreco = (centavos) =>
(centavos / 100).toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
function precoDoProduto(slug) {
return PRECO_POR_KG_EM_CENTAVOS[slug] ?? 0;
}
function subtotal(slug, quilos) {
if (quilos <= 0) return 0;
return Math.round(precoDoProduto(slug) * quilos);
}
function totalDoCarrinho(itens) {
return itens.reduce((soma, item) => soma + subtotal(item.slug, item.quilos), 0);
}
const carrinho = [
{ slug: "farinha", quilos: 3 },
{ slug: "acai", quilos: 2 },
];
console.log(formatarPreco(totalDoCarrinho(carrinho))); // → R$ 87,50
Cada função faz uma coisa, todas são puras, e todas podem ser testadas isoladamente.
Exercícios
- Escreva uma função que receba centavos e devolva o valor formatado.
- Escreva a mesma função nas três formas: declaração, expressão e arrow.
- Escreva uma que classifique a idade em quatro faixas.
- Escreva uma sem
returne confira o que ela devolve. - Tente acessar uma variável interna de fora e leia o erro.
- Pegue uma função que mexe em variável de fora e reescreva-a como pura.
- Monte o conjunto de funções do carrinho e some um pedido de três itens.
Referências
- Funções - MDN - a introdução
- Arrow functions - MDN - sintaxe e diferenças
- Escopo - MDN - o que é visível de onde
Testa o que você leu
5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.