Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIniciantecódigo testado

Parâmetros e retorno de função em JavaScript

JavaScript não confere quantos argumentos você passou. Veja parâmetro padrão, rest, o objeto arguments e o return que devolve undefined sem avisar ninguém.

Rodolfo Mori7 min de leitura

Parâmetro é o nome que a função dá ao valor que vai receber; retorno é o valor que ela devolve para quem chamou. A resposta curta, que economiza uma hora de depuração: JavaScript não confere a quantidade de argumentos — argumento que falta vira undefined, argumento a mais é descartado em silêncio, e nenhum dos dois casos gera erro na hora.

Isso é diferente de quase toda linguagem que você vai encontrar depois. Em Python, chamar uma função sem um argumento obrigatório derruba o programa na hora. Em JavaScript o programa continua, com um undefined circulando, e o erro estoura três funções adiante — no lugar errado.

Os exemplos aqui são de uma loja virtual, os mesmos objetos de funções em JavaScript: pedido, frete, cupom, etiqueta de envio.

Formulário de entrada e recibo de saída

Uma função se parece com um balcão de serviço. O formulário do balcão define os campos esperados — destino, peso, modalidade — e cada cliente preenche esses campos com valores concretos. Depois do trabalho, o balcão entrega um recibo com o resultado.

Na linguagem, os nomes do formulário são parâmetros, os valores entregues na chamada são argumentos e o recibo é o retorno. Leia a primeira chamada em duas etapas: associe cada argumento ao parâmetro correspondente e só depois calcule o return. A saída permite conferir as duas associações, inclusive o undefined de um campo que não veio.

Os dois termos costumam ser usados como sinônimos e não são. Parâmetro é a variável declarada entre os parênteses da função; ela só existe lá dentro. Argumento é o valor concreto que você passa na chamada.

js
function calcularParcela(total, vezes) {
  return total / vezes;
}

console.log(calcularParcela(1299, 12));
console.log(calcularParcela(89.9, 3));
108.25 29.96666666666667

total e vezes são parâmetros. 1299 e 12 são argumentos. A distinção importa na hora de ler mensagem de erro: o Node cita o nome que existe dentro da função. Uma reclamação sobre vezes não diz nada sobre qual chamada estava errada — cabe a você descobrir qual delas esqueceu o segundo argumento.

O segundo número tem quatorze casas decimais porque números com fração em JavaScript são ponto flutuante binário. Para dinheiro, formate na saída com toFixed(2) ou guarde tudo em centavos.

JavaScript não confere a quantidade de argumentos

Esta função pede três valores. Veja o que acontece quando ela recebe um, e quando recebe cinco.

js
function montarEtiqueta(cliente, cidade, uf) {
  return `${cliente} — ${cidade}/${uf}`;
}

console.log(montarEtiqueta('Ana Souza', 'Recife', 'PE'));
console.log(montarEtiqueta('Bruno Lima'));
console.log(montarEtiqueta('Carla Dias', 'Curitiba', 'PR', 'ignorado', 42));
Ana Souza — Recife/PE Bruno Lima — undefined/undefined Carla Dias — Curitiba/PR

Nenhuma exceção. A segunda etiqueta saiu com undefined/undefined impresso como se fosse endereço, e a terceira descartou dois argumentos sem comentar. Se essa etiqueta fosse para a transportadora, o pacote sairia com o texto literal undefined no destino.

A própria função sabe da diferença — você é que precisa perguntar:

js
function montarEtiqueta(cliente, cidade, uf) {
  console.log('declarados:', montarEtiqueta.length, '| recebidos:', arguments.length);
  return `${cliente} — ${cidade}/${uf}`;
}

montarEtiqueta('Bruno Lima');
montarEtiqueta('Carla Dias', 'Curitiba', 'PR', 'ignorado');
declarados: 3 | recebidos: 1 declarados: 3 | recebidos: 4

fn.length é a aridade declarada; arguments.length é o que chegou de fato. Em código de produção você não fica comparando os dois — você declara parâmetro padrão ou valida a entrada logo na primeira linha e devolve um erro com nome.

Parâmetro padrão

Um parâmetro pode carregar um valor de reserva, usado quando o argumento não vem. E o padrão pode ser uma expressão — inclusive uma que usa os parâmetros declarados antes dele.

js
function calcularFrete(peso, taxaPorKg = 2.5, minimo = taxaPorKg * 4) {
  return Math.max(peso * taxaPorKg, minimo);
}

console.log(calcularFrete(1));
console.log(calcularFrete(8));
console.log(calcularFrete(8, 4));
console.log(calcularFrete(8, 4, 50));
10 20 32 50

Na primeira chamada, minimo valeu 2.5 * 4 = 10 e ganhou do cálculo por peso. Na terceira, taxaPorKg virou 4, e o minimo — que depende dele — recalculou para 16 sozinho. Os padrões são avaliados na hora da chamada, da esquerda para a direita, e não uma única vez na definição.

A ordem importa: se minimo viesse antes de taxaPorKg na lista, o padrão tentaria ler uma variável que ainda está na zona morta temporal e o Node lançaria ReferenceError. É o mesmo mecanismo que a lição de hoisting em JavaScript destrincha.

O padrão só entra para undefined

Esta é a pegadinha que aparece em formulário e em resposta de API.

js
function aplicarCupom(valor, desconto = 10) {
  return valor - desconto;
}

console.log(aplicarCupom(200));
console.log(aplicarCupom(200, undefined));
console.log(aplicarCupom(200, null));
console.log(aplicarCupom(200, 0));
console.log(aplicarCupom(200, ''));
190 190 200 200 200

undefined aciona o padrão. null, 0 e string vazia não — são valores legítimos, e o motor respeita. Um null vindo do banco virou zero na subtração e ninguém foi avisado. Se o valor pode chegar como null, trate com ?? dentro do corpo: const abatimento = desconto ?? 10.

Rest: o que sobrar vira array

Três pontos antes do último parâmetro recolhem todos os argumentos restantes num array de verdade.

js
function fecharPedido(cliente, ...precos) {
  const total = precos.reduce((soma, preco) => soma + preco, 0);
  return { cliente, itens: precos.length, total: Number(total.toFixed(2)) };
}

const carrinho = [289.9, 149.9, 39.9];

console.log(fecharPedido('Ana Souza', ...carrinho));
console.log(fecharPedido('Bruno Lima'));
console.log('length ignora o rest:', fecharPedido.length);
{ cliente: 'Ana Souza', itens: 3, total: 479.7 } { cliente: 'Bruno Lima', itens: 0, total: 0 } length ignora o rest: 1

Três detalhes que valem guardar. Sem argumentos extras, precos é um array vazio, nunca undefined — por isso o reduce roda sem nenhuma verificação. Os mesmos três pontos, do lado da chamada, fazem o contrário: espalham o array em argumentos soltos. E fn.length conta 1, porque o rest não entra na aridade declarada.

arguments, o objeto que a arrow não tem

Antes do rest existir, a única forma de pegar argumentos extras era o objeto arguments, criado automaticamente dentro de toda função function. Ele parece um array, mas não é: não tem map, não tem reduce, e precisa de Array.from para virar um.

Em arrow function ele simplesmente não existe:

js
const somarPrecos = () => {
  return Array.from(arguments).reduce((soma, preco) => soma + preco, 0);
};

console.log(somarPrecos(19.9, 49.9, 129.9));
file:///private/tmp/loja/arguments-arrow.mjs:2 return Array.from(arguments).reduce((soma, preco) => soma + preco, 0); ^

ReferenceError: arguments is not defined at somarPrecos (file:///private/tmp/loja/arguments-arrow.mjs:2:21) at file:///private/tmp/loja/arguments-arrow.mjs:5:13 at ModuleJob.run (node:internal/modules/esm/module_job:439:25)

Node.js v24.16.0

is not defined, e não is not a function: para o motor, arguments ali é um nome que nunca existiu. Trocar a arrow por function faz o código voltar a rodar — mas o certo é trocar arguments por rest e resolver de vez.

return devolve um valor e encerra a função

Sem return, a função devolve undefined. Com return sozinho, também. E qualquer linha depois de um return executado nunca roda.

js
function registrarLog(pedido) {
  console.log(`[pedido ${pedido.id}] R$ ${pedido.total.toFixed(2)}`);
}

function validarCep(cep) {
  if (cep.length !== 8) {
    return;
  }
  return true;
}

console.log(registrarLog({ id: 7412, total: 479.7 }));
console.log(validarCep('01310100'));
console.log(validarCep('0131'));
[pedido 7412] R$ 479.70 undefined true undefined

registrarLog imprimiu e devolveu undefined: imprimir é conversa com você, devolver é conversa com o resto do programa. validarCep usou o return seco como saída antecipada — padrão comum e legítimo, desde que quem chama saiba que o “falso” dessa função é undefined, não false.

Devolver mais de uma informação

JavaScript devolve um valor por chamada. Quando você precisa de dois, devolva um objeto e desestruture do outro lado.

js
function separarFrete(subtotal) {
  const frete = subtotal >= 199 ? 0 : 24.9;
  return { subtotal, frete, aPagar: Number((subtotal + frete).toFixed(2)) };
}

const { frete, aPagar } = separarFrete(150);
console.log(frete, aPagar);
console.log(separarFrete(250));
24.9 174.9 { subtotal: 250, frete: 0, aPagar: 250 }

A vantagem sobre devolver um array ([frete, aPagar]) é que o nome vem junto: quem lê a chamada não precisa lembrar a ordem, e você pode acrescentar um campo no retorno sem quebrar o código de ninguém.

Erros comuns: o return que devolve undefined

Este é o erro característico da lição, e ele não vem de digitar errado — vem de formatar bonito. O JavaScript insere ponto e vírgula automaticamente (ASI) no fim de uma linha que começa com return. Quebrar a linha depois do return termina a instrução ali.

js
function montarResumo(cliente, total) {
  return
    { cliente, total };
}

const resumo = montarResumo('Ana Souza', 479.7);
console.log(resumo.cliente);
file:///private/tmp/loja/asi-return.mjs:7 console.log(resumo.cliente); ^

TypeError: Cannot read properties of undefined (reading ‘cliente’) at file:///private/tmp/loja/asi-return.mjs:7:20 at ModuleJob.run (node:internal/modules/esm/module_job:439:25)

Node.js v24.16.0

Repare no ponto em que o erro estourou: linha 7, na hora de ler .cliente. A função da linha 1 é a culpada e nem aparece no rastro. O motor leu return; e depois um bloco solto com uma expressão dentro — código válido, que nunca é alcançado, e nenhum aviso é emitido.

A correção é manter a chave de abertura na mesma linha do return:

js
function montarResumo(cliente, total) {
  return {
    cliente,
    total,
  };
}

console.log(montarResumo('Ana Souza', 479.7));
{ cliente: 'Ana Souza', total: 479.7 }

Essa é uma das quatro origens do TypeError: Cannot read properties of undefined, e a mais chata de achar, porque o undefined nasce numa linha e mata em outra. Um formatador como o Prettier nunca quebra a linha depois de return — vale deixar ele ligado só por isso.

Como desenhar a assinatura de uma função

A lista de parâmetros é o contrato público da sua função. Três regras que seguram bem no dia a dia:

  • Obrigatórios primeiro, opcionais com padrão depois. Se o opcional vier no meio, quem chama precisa escrever undefined para pular — e isso já é sinal de que a assinatura está errada.
  • A partir do quarto parâmetro, troque por um objeto. criarPedido({ cliente, cep, itens, cupom }) sobrevive a mudanças; criarPedido(cliente, cep, itens, cupom) obriga todo mundo a lembrar a ordem.
  • Boolean na chamada é uma armadilha. calcularFrete(2, true) não diz nada. calcularFrete(2, { expresso: true }) diz tudo, no mesmo número de teclas.

E do lado do retorno: devolva sempre o mesmo formato. Uma função que às vezes devolve um número e às vezes undefined obriga quem chama a testar antes de usar — o que quase sempre significa que alguém vai esquecer.

A próxima lição da trilha de JavaScript mostra que a forma de declarar a função também muda o comportamento, e não só o estilo: function expression contra function declaration. O guia completo de JavaScript tem a sequência inteira em ordem de estudo.

Prefere aprender em vídeo?

Tem uma aula sobre este assunto no nosso canal.

Ver todos os vídeos do canal
  • parametros
  • retorno
  • rest
  • parametro padrao
  • arguments

Perguntas frequentes

O que acontece se eu passar menos argumentos do que a função pede?
Nada acontece na hora: os parâmetros que sobraram valem undefined e a função roda até o fim. O erro só aparece quando alguém tenta usar esse undefined, geralmente algumas linhas depois — por isso o rastro leva ao lugar errado. Parâmetro padrão e validação na entrada resolvem.
Parâmetro padrão pode usar outro parâmetro?
Pode, desde que o outro venha antes na lista. Os padrões são avaliados da esquerda para a direita, na hora da chamada, então frete = taxa * 4 funciona se taxa estiver declarada antes. Ao contrário, dá ReferenceError de zona morta temporal.
Ainda vale a pena aprender o objeto arguments?
Só para ler código antigo. Ele não existe em arrow function, não é um array de verdade e não enxerga parâmetros padrão. Em código novo, rest faz o mesmo trabalho, é um array real e aparece na assinatura.
Quantos parâmetros são demais?
A partir do quarto, a chamada vira um enigma posicional — ninguém lembra se a data vem antes ou depois do CEP. Troque a lista por um único objeto com nomes; de quebra você ganha a possibilidade de omitir campos sem escrever undefined no meio da chamada.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em Node 24.16.0, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. MDN — Functions: parâmetros default — developer.mozilla.org
  2. MDN — Rest parameters — developer.mozilla.org
  3. ECMAScript 2026 — Function Definitions — tc39.es

Continue por aqui