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

console.log: como imprimir valores no JavaScript

Imprimir valor, objeto e lista no JavaScript com log, table e dir — o que o console esconde por profundidade e por que o objeto logado engana.

Rodolfo Mori6 min de leitura

console.log é um método da API console que registra valores enquanto o programa executa. Ele aceita texto, número, objeto, array e outros valores e os envia ao console do ambiente — DevTools no navegador ou saída padrão no Node.

Pense no log como um painel de instrumentos. Ele não dirige o carro nem conserta o motor; apenas mostra velocidade, temperatura e alertas no ponto em que você resolveu medir. No código acontece o mesmo: console.log não altera o valor nem o devolve para a próxima função. Ele torna uma observação visível para responder à pergunta mais útil de uma depuração: o valor aqui é o que eu esperava?

Esta é a terceira lição da trilha de JavaScript, e ela vem antes de variáveis de propósito: sem imprimir, não dá para conferir nada do que vem depois.

Imprimir o primeiro valor

js
const cliente = 'Ana Souza';
const itens = 3;

console.log(cliente);
console.log(cliente, itens);
console.log(`${cliente} tem ${itens} itens`);
Ana Souza Ana Souza 3 Ana Souza tem 3 itens

Três formas, três resultados diferentes. Passar vários argumentos separados por vírgula imprime todos numa linha, com um espaço entre eles — sem você precisar concatenar nada. A terceira usa template string: crase no lugar da aspa e ${} em volta do que deve ser avaliado.

A vírgula tem uma vantagem escondida sobre a template string: ela preserva o tipo. console.log('total:', 289.9) mostra o número como número; dentro de uma template string tudo vira texto.

Marcadores de formatação: %s, %d, %o

Quando o primeiro argumento é uma string com marcadores, o console os substitui pelos argumentos seguintes:

js
const pedido = { id: 4821, total: 589.7 };

console.log('pedido %d fechado em R$ %s', pedido.id, pedido.total.toFixed(2));
console.log('pedido inteiro: %o', pedido);
console.log('%s levou %i itens', 'Ana', 3.9);
pedido 4821 fechado em R$ 589.70 pedido inteiro: { id: 4821, total: 589.7 } Ana levou 3 itens

Repare no %i da última linha: ele truncou 3.9 para 3. %d e %i forçam número, %s força texto, %o imprime a estrutura do objeto. Não é obrigatório usar — mas quando você vir isso em código alheio, agora sabe o que é.

console.table: lista de objetos vira tabela

Este é o comando mais subutilizado do console. Quando o valor é um array de objetos com as mesmas chaves, ele desenha uma tabela:

js
const carrinho = [
  { produto: 'Teclado mecânico', qtd: 1, preco: 289.9 },
  { produto: 'Mouse sem fio', qtd: 2, preco: 149.9 },
  { produto: 'Mousepad XL', qtd: 1, preco: 79.9 },
];

console.table(carrinho);
┌─────────┬────────────────────┬─────┬───────┐ │ (index) │ produto │ qtd │ preco │ ├─────────┼────────────────────┼─────┼───────┤ │ 0 │ 'Teclado mecânico' │ 1 │ 289.9 │ │ 1 │ 'Mouse sem fio' │ 2 │ 149.9 │ │ 2 │ 'Mousepad XL' │ 1 │ 79.9 │ └─────────┴────────────────────┴─────┴───────┘

Com muitas colunas a tabela fica larga demais para o terminal. O segundo argumento escolhe quais aparecem:

js
console.table(carrinho, ['produto', 'preco']);
┌─────────┬────────────────────┬───────┐ │ (index) │ produto │ preco │ ├─────────┼────────────────────┼───────┤ │ 0 │ 'Teclado mecânico' │ 289.9 │ │ 1 │ 'Mouse sem fio' │ 149.9 │ │ 2 │ 'Mousepad XL' │ 79.9 │ └─────────┴────────────────────┴───────┘

Para conferir uma lista de dados que veio de uma API, console.table responde em um segundo o que um log normal responderia em dez.

O log corta o que está fundo demais

Aqui está a primeira coisa que o console faz pelas suas costas. No Node, ele imprime objetos até dois níveis de profundidade e resume o resto:

js
const pedido = {
  id: 4821,
  cliente: {
    nome: 'Ana Souza',
    endereco: { cidade: 'São Paulo', geo: { lat: -23.5613, lng: -46.6565 } },
  },
};

console.log(pedido);
console.dir(pedido, { depth: null });
{ id: 4821, cliente: { nome: 'Ana Souza', endereco: { cidade: 'São Paulo', geo: [Object] } } } { id: 4821, cliente: { nome: 'Ana Souza', endereco: { cidade: 'São Paulo', geo: { lat: -23.5613, lng: -46.6565 } } } }

Aquele [Object] não é um objeto vazio nem um erro: é o console dizendo “tem mais coisa aqui, e eu resolvi não mostrar”. Muita gente perde meia hora achando que o dado não chegou. console.dir com depth: null imprime tudo.

O objeto que você logou não é uma foto

Este é o comportamento que mais engana, e ele muda de ambiente para ambiente. No Node, o console converte o objeto em texto na hora da chamada:

js
const carrinho = { itens: [] };

console.log(carrinho);

carrinho.itens.push('Teclado mecânico');
carrinho.itens.push('Mouse sem fio');

console.log(carrinho);
{ itens: [] } { itens: [ 'Teclado mecânico', 'Mouse sem fio' ] }

Comportamento previsível: o primeiro log mostra o carrinho vazio, porque naquele instante ele estava vazio.

No console do navegador, o mesmo código imprime uma linha recolhida com um triângulo ao lado — e o DevTools guardou uma referência ao objeto, não uma cópia. Quando você clica para expandir, ele lê o objeto naquele momento, já com os dois itens dentro. O log parece mentir sobre o passado, e há anos isso faz gente duvidar do próprio código.

Duas saídas quando você precisa do estado exato de um objeto num ponto do tempo:

js
const carrinho = { itens: ['Teclado mecânico'] };

console.log(JSON.stringify(carrinho));
console.log(structuredClone(carrinho));
{"itens":["Teclado mecânico"]} { itens: [ 'Teclado mecânico' ] }

JSON.stringify congela em texto; structuredClone faz uma cópia profunda que o DevTools não tem como atualizar depois. Qualquer uma resolve.

stdout e stderr: warn e error saem por outro cano

console.log escreve na saída padrão. console.error e console.warn escrevem na saída de erro. No terminal os dois aparecem misturados, o que dá a impressão de serem a mesma coisa:

js
console.log('subtotal calculado');
console.error('cupom expirado');
console.warn('estoque baixo');
subtotal calculado cupom expirado estoque baixo

Mas são canos separados, e isso importa no dia em que você for filtrar um log de servidor:

bash
node saida.mjs 1> /dev/null
cupom expirado estoque baixo

Descartando a saída padrão, sobraram só o erro e o aviso. É assim que ferramenta de monitoramento separa ruído de problema — e é por isso que mensagem de falha vai em console.error, não em console.log.

Medir e contar: time, timeEnd e count

Dois utilitários que substituem gambiarra com Date.now():

js
console.time('somar precos');

const precos = Array.from({ length: 1_000_000 }, (_, i) => i / 100);
const total = precos.reduce((soma, preco) => soma + preco, 0);

console.timeEnd('somar precos');
console.log('total:', total.toFixed(2));
somar precos: 33.226ms total: 4999995000.00

E console.count, que conta quantas vezes aquela linha passou por ali — ótimo para descobrir que uma função está sendo chamada três vezes quando deveria ser uma:

js
const carrinho = ['Teclado mecânico', 'Mouse sem fio', 'Teclado mecânico'];

for (const item of carrinho) console.count(item);
Teclado mecânico: 1 Mouse sem fio: 1 Teclado mecânico: 2

Erros comuns

O tropeço clássico é trocar console.log por alert — que muita apostila antiga ainda ensina. alert não é linguagem, é uma função do navegador; no Node ela simplesmente não existe:

js
const total = 589.7;

alert(`Total: R$ ${total.toFixed(2)}`);
file:///private/tmp/loja/l3-alert.mjs:3 alert(`Total: R$ ${total.toFixed(2)}`); ^

ReferenceError: alert is not defined at file:///private/tmp/loja/l3-alert.mjs:3:1 Node.js v24.16.0

E mesmo no navegador, onde existe, alert é má ideia para depurar: ele trava a thread. Enquanto a caixa estiver aberta, nada roda — nem animação, nem requisição pendente, nem o resto do seu código. Depurar um laço com alert significa clicar em OK trinta vezes.

Os outros dois:

  • Logar dentro de um laço grande. Cem mil linhas no terminal levam mais tempo que a conta que você queria medir. Use console.count ou logue a cada mil voltas.
  • Achar que console.log devolve alguma coisa. Ele devolve undefined. const x = console.log('oi') deixa x valendo undefined, e a diferença entre imprimir e retornar é o assunto de null, undefined e NaN.

O que fica no código e o que sai antes do commit

Log de investigação — aquele console.log('cheguei aqui') — é rascunho: apague antes de commitar. Log de operação, num servidor Node, é outra coisa e pode ficar, desde que diga algo útil e não despeje objeto inteiro no terminal.

No navegador, tudo que sobra fica visível para quem abrir o DevTools do seu site, inclusive dados de cliente. Não é só desleixo estético.

Faça uma investigação curta: crie um objeto pedido, registre o objeto inteiro, depois pedido.total e por fim typeof pedido.total. Altere o total e repita. Você deve conseguir responder três perguntas separadas: qual é o valor, onde ele está e qual é seu tipo. Termine removendo os logs de investigação e mantendo apenas uma mensagem operacional sem dados pessoais.

A próxima lição da trilha é sobre variáveis: como declarar e usar — a partir daí todo exemplo vai ter algo guardado para você imprimir. O guia de JavaScript mostra a sequência completa, e a página de JavaScript por tecnologia reúne tudo que já foi publicado sobre a linguagem.

  • javascript
  • console
  • depuracao
  • node
  • devtools

Perguntas frequentes

Qual a diferença entre console.log e alert?
console.log escreve no console e o programa continua. alert abre uma caixa que trava a página até alguém clicar em OK, e só existe no navegador. Para depurar, log sempre; alert só para avisar uma pessoa.
Por que meu objeto aparece como [Object] no terminal?
O Node imprime objetos até dois níveis de profundidade e resume o que estiver mais fundo. Use console.dir com depth null, ou imprima direto a parte que interessa em vez do objeto inteiro.
Posso deixar console.log no código que vai para produção?
Em servidor Node, log é a forma normal de observar a aplicação — mas estruturado, não solto. No navegador, log esquecido vaza dado no console de quem visita e deixa a impressão de código não terminado.
console.log é lento?
Numa linha ou outra, não faz diferença. Dentro de um laço com centenas de milhares de voltas, faz: escrever no terminal é entrada e saída, e chega a dominar o tempo do trecho que você está medindo.

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 — Console — developer.mozilla.org
  2. Node.js — Console API — nodejs.org

Continue por aqui