O console vai muito além do console.log
O console.log costuma ser a primeira ferramenta de debug que a gente aprende em JavaScript — e, para muita gente, é também a última que deixa de usar. Ele funciona, sim, mas o objeto console tem uma dezena de outros métodos que deixam a depuração mais rápida e muito mais clara. E, quando você se sentir à vontade no DevTools de verdade (breakpoints, call stack, watch expressions), vai perceber que recorre ao log bem menos do que antes.
Vamos começar com um tour rápido:
Os quatro métodos jogam tudo no mesmo console, mas cada navegador aplica um estilo próprio: avisos aparecem com fundo amarelo, erros ganham fundo vermelho e um ícone, e ambos trazem o stack trace junto. Os filtros do DevTools permitem esconder ou isolar cada nível, o que faz toda a diferença quando a aplicação começa a cuspir centenas de mensagens.
Logando vários valores do jeito preguiçoso
Quando você precisa inspecionar várias variáveis ao mesmo tempo, evite concatenar tudo numa string só. Passe cada uma como argumento separado — ou, melhor ainda, coloque dentro de um objeto para que cada valor apareça com seu nome:
O truque do { user, count } aproveita o shorthand de objeto: o nome da variável vira a chave. No console, você vai ver { user: {...}, count: 3 } e consegue expandir o user para inspecionar o conteúdo. Assim você não perde a estrutura do objeto convertendo tudo em string.
console.table no JavaScript: visualizando arrays de objetos
Quando você precisa analisar um array de objetos, o console.log te entrega uma bagunça toda colapsada. Já o console.table mostra os dados como uma tabela de verdade:
No console do navegador, a primeira chamada mostra as três linhas com colunas ordenáveis. Já a segunda limita a saída só a name e role. Para qualquer coisa que tenha formato de dados — respostas de API, resultados de query, CSVs parseados — esse recurso é uma mão na roda.
console.dir vs console.log no JavaScript
Parecem iguais, mas se comportam de maneiras bem diferentes quando o assunto é elemento do DOM:
const el = document.querySelector("button");
console.log(el); // imprime o HTML: <button>Click me</button>
console.dir(el); // imprime a visualização do objeto JS com todas as propriedades
log mostra os elementos formatados como HTML. Já o dir exibe o objeto de verdade — cada propriedade, cada manipulador de evento, cada referência de estilo computado. Quando você quer saber quais métodos ou atributos um elemento tem, o dir é a pedida.
Agrupando saídas relacionadas no console
Sessões longas de debug enchem o console de ruído. O console.group junto com o console.groupEnd agrupam mensagens relacionadas em um bloco que dá pra recolher:
Cada chamada cria um grupo nomeado que você pode recolher. Se quiser que os grupos já comecem fechados, use console.groupCollapsed — super útil quando você só quer abrir aqueles que parecem suspeitos.
Medindo tempo de execução com console.time
Para medições rápidas de desempenho no JavaScript, é difícil superar a dupla console.time e console.timeEnd:
O rótulo usado no time precisa ser o mesmo no timeEnd. Dá pra ter vários timers rodando ao mesmo tempo, cada um com um rótulo diferente. Agora, se o seu objetivo vai além de responder "esse loop tá lento?", vale a pena abrir a aba Performance do DevTools, que grava uma timeline completa e monta um flame chart.
Assertions: só logar quando algo der errado
O console.assert só imprime quando a condição é falsa. É um jeito discreto de deixar verificações de sanidade no código sem encher o console de mensagens quando está tudo certo:
Útil para invariantes que deveriam sempre ser verdadeiros. Ruim para coisas que podem falhar legitimamente — nesses casos, lance um erro.
Stack traces sob demanda
O console.trace imprime a pilha de chamadas atual sem lançar exceção nenhuma. Bem útil quando você quer descobrir quem chamou determinada função:
O resultado mostra inner → outer → (top level). Numa aplicação real, é assim que você descobre que aquele click handler que está debugando está sendo disparado por três lugares diferentes.
A instrução debugger
A forma mais rápida de pausar a execução do JavaScript é com uma única palavra:
function computeTotal(items) {
const subtotal = items.reduce((s, i) => s + i.price, 0);
debugger;
return subtotal * 1.08;
}
Com o DevTools aberto, o debugger; funciona como um breakpoint — a execução pausa naquela linha e você ganha acesso ao depurador completo: variáveis em escopo, pilha de chamadas, controles de step-over e step-into, além de poder avaliar expressões no estado atual. Com o DevTools fechado, o debugger; simplesmente não faz nada.
Da primeira vez que você usa um depurador de verdade no lugar do console.log, a sensação é de superpoder. Dá pra ver todas as variáveis em escopo sem precisar decidir antes o que imprimir. Você percorre as condicionais passo a passo e observa qual ramo é executado. Aquele bug chato que levaria minutos pra resolver cai pra segundos.
Lembre-se de remover a linha debugger antes de commitar — ou, melhor ainda, defina breakpoints direto no DevTools clicando no número da linha no painel Sources.
Truques do DevTools que vale a pena conhecer
Alguns recursos que muita gente passa anos sem descobrir:
- Breakpoints condicionais: clique com o botão direito no número da linha no Sources e defina uma condição, tipo
user.id === 42. O breakpoint só dispara quando a condição for verdadeira. - Logpoints: no mesmo menu, "Add logpoint." Imprime uma mensagem sem pausar e sem precisar mexer no seu código.
$_no console: guarda a última expressão avaliada. Rode algo e use$_pra pegar o resultado.$0: o elemento selecionado no momento no painel Elements.$0.textContentinspeciona o que quer que você tenha clicado.- Copiar como objeto: clique com o botão direito em qualquer valor no console e escolha "Store as global variable." Você recebe
temp1,temp2, etc., pra brincar à vontade. - Painel Network → Copy as fetch: transforma qualquer requisição numa chamada
fetch()que dá pra colar no console e ajustar.
Nenhum deles é essencial. Mas todos economizam tempo quando entram na memória muscular.
Limpando tudo antes do deploy
Chamadas de console.log esquecidas são inofensivas em desenvolvimento, mas barulhentas em produção. Alguns hábitos que ajudam:
- Use uma regra de lint (
no-consoleno ESLint) pra sinalizar logs perdidos, com exceções prawarneerror. - Envolva logs verbosos numa verificação:
if (process.env.NODE_ENV !== "production") console.log(...). - Prefira
console.debugpra saída de nível trace — a maioria dos bundlers e agregadores de log consegue filtrar esse tipo. - Melhor ainda: use um módulo de logger próprio (ou uma lib como
debug) pra ligar e desligar categorias de log sem editar código.
Logar não sai de graça. Cada chamada serializa os argumentos e escreve num buffer. Num loop quente, um log esquecido pode deixar tudo visivelmente mais lento.
A seguir: Expressões regulares
Você vai debugar bastante código de processamento de strings, e boa parte desse código usa regex — o recurso mais compacto e também mais enigmático da linguagem. O próximo capítulo abre com um tour tranquilo pelas expressões regulares em JavaScript e pelos métodos que as utilizam.
Perguntas frequentes
Qual a diferença entre console.log e console.dir?
O console.log imprime os valores usando a formatação padrão do navegador — no caso de elementos do DOM, isso significa exibi-los como HTML. Já o console.dir sempre mostra a visão do objeto JavaScript com todas as propriedades, que é o que você quer quando precisa inspecionar as propriedades de um elemento em vez da marcação.
Como debugar JavaScript no Chrome DevTools sem usar console.log?
Abra o painel Sources, localize o seu arquivo e clique no número da linha para colocar um breakpoint. Quando a execução chegar ali, ela pausa e você consegue inspecionar variáveis, avançar passo a passo e executar expressões no console. Outra opção é jogar um debugger; direto no código para disparar um breakpoint a partir do próprio fonte.
Como medir quanto tempo um trecho de JavaScript leva para rodar?
Envolva o código com console.time('label') e console.timeEnd('label'), usando o mesmo rótulo nos dois. O console mostra o tempo decorrido em milissegundos. Para uma análise mais detalhada, use o painel Performance do DevTools e grave um flame chart de tudo o que foi executado.
Para que serve o console.table?
O console.table exibe arrays e objetos como uma tabela ordenável no console, muito mais fácil de ler do que um objeto aninhado gigante. É perfeito para arrays de objetos — cada objeto vira uma linha e suas chaves viram colunas. Dá até para passar um segundo argumento limitando quais colunas aparecem.