Pular para o conteúdo

A primeira escola especializada em tecnologia do Alto Solimões, com corpo técnico formado na área.

Módulo 4: Funções

Funções e arrow functions

Dar nome a um trecho de código

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

  1. Escreva uma função que receba centavos e devolva o valor formatado.
  2. Escreva a mesma função nas três formas: declaração, expressão e arrow.
  3. Escreva uma que classifique a idade em quatro faixas.
  4. Escreva uma sem return e confira o que ela devolve.
  5. Tente acessar uma variável interna de fora e leia o erro.
  6. Pegue uma função que mexe em variável de fora e reescreva-a como pura.
  7. Monte o conjunto de funções do carrinho e some um pedido de três itens.

Referências

Testa o que você leu

5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.

Pergunta 1 de 5
O que uma função devolve quando chega ao fim sem `return`?