Menu

Consola y DevTools en JavaScript: más allá de console.log

Los métodos de consola y las funciones de DevTools que hacen que depurar JavaScript sea mucho más rápido que llenar el código de console.log.

La consola es mucho más que log

console.log suele ser la primera herramienta de depuración que aprendemos, y para muchos también la última que dejan de usar. Funciona, sí, pero el objeto console tiene una docena de métodos más que hacen que depurar sea más rápido y claro. Y cuando empieces a moverte con soltura dentro de las DevTools —breakpoints, pila de llamadas, expresiones de inspección—, vas a recurrir a log bastante menos que antes.

Empecemos con un repaso rápido:

index.js
Output
Click Run to see the output here.

Los cuatro métodos imprimen en la misma consola, pero cada navegador los muestra con un estilo distinto: los avisos salen con fondo amarillo, los errores en rojo y con un icono, y ambos incluyen el stack trace. Los filtros de DevTools permiten ocultar o aislar cada nivel, algo que se agradece cuando la aplicación empieza a escupir cientos de mensajes.

Mostrar varias variables sin complicarse

Cuando quieras inspeccionar varias variables a la vez, no las concatenes en un string. Pásalas como argumentos separados o, mejor aún, envuélvelas en un objeto para que cada una aparezca con su etiqueta:

index.js
Output
Click Run to see the output here.

El truco de { user, count } aprovecha la sintaxis abreviada de objetos: el nombre de la variable se convierte en la clave. En la consola verás { user: {...}, count: 3 } y podrás expandir user para inspeccionarlo. Así no pierdes la estructura del objeto al convertirlo a string.

console.table en JavaScript para arrays de objetos

Cuando tienes delante un array de objetos, console.log te devuelve un amasijo colapsado difícil de leer. console.table lo pinta como una tabla de verdad:

index.js
Output
Click Run to see the output here.

En la consola del navegador, la primera llamada pinta las tres filas con columnas ordenables. La segunda la acota a name y role. Es un salto brutal de comodidad cuando trabajas con datos tabulares: respuestas de APIs, resultados de queries, CSVs parseados…

console.dir vs console.log

A primera vista parecen lo mismo, pero con elementos del DOM se comportan de forma distinta:

const el = document.querySelector("button");

console.log(el);   // prints the HTML: <button>Click me</button>
console.dir(el);   // prints the JS object view with all properties

log muestra los elementos con formato HTML. dir, en cambio, te muestra el objeto tal cual: todas sus propiedades, cada manejador de eventos, cada referencia a estilos computados. Cuando necesites saber qué métodos o atributos tiene un elemento, tira de dir.

Agrupar salida relacionada con console.group

En sesiones de depuración largas la consola termina llena de ruido. Con console.group y console.groupEnd puedes envolver mensajes relacionados en un bloque plegable:

index.js
Output
Click Run to see the output here.

Cada llamada genera un grupo con nombre que puedes colapsar. Usa console.groupCollapsed si prefieres que los grupos aparezcan plegados al principio: te viene bien cuando solo quieres abrir los que parecen sospechosos.

Medir tiempo de ejecución en JavaScript con console.time

Para mediciones rápidas de rendimiento, es difícil superar a console.time y console.timeEnd:

index.js
Output
Click Run to see the output here.

Las etiquetas de time y timeEnd tienen que coincidir. Puedes tener varios temporizadores corriendo al mismo tiempo con etiquetas distintas. Para algo más serio que un simple "¿este bucle va lento?", mejor pásate al panel Performance de DevTools, que graba una línea de tiempo completa y un flame chart.

Aserciones: loguear solo cuando algo va mal

console.assert solo imprime cuando la condición es falsy. Es una forma silenciosa de dejar comprobaciones de sanidad en tu código sin llenar la consola cuando todo va bien:

index.js
Output
Click Run to see the output here.

Útil para invariantes que deberían cumplirse siempre. Mala idea para cosas que podrían fallar legítimamente — para esos casos, lanza un error.

Imprimir el stack trace cuando lo necesites

console.trace imprime la pila de llamadas actual sin lanzar ninguna excepción. Viene genial cuando quieres averiguar quién llamó a una función:

index.js
Output
Click Run to see the output here.

La salida muestra inner → outer → (top level). En una aplicación real, así es como descubres que el manejador de clic que estás depurando se dispara desde tres sitios distintos.

La sentencia debugger en JavaScript

La forma más rápida de pausar la ejecución de JavaScript cabe en una sola palabra:

function computeTotal(items) {
    const subtotal = items.reduce((s, i) => s + i.price, 0);
    debugger;
    return subtotal * 1.08;
}

Con DevTools abierto, debugger; funciona como un breakpoint: la ejecución se detiene en esa línea y tienes el depurador completo a tu disposición — variables en el ámbito actual, la pila de llamadas, los controles para avanzar paso a paso (step-over y step-into) y la posibilidad de evaluar expresiones contra el estado actual. Si DevTools está cerrado, debugger; simplemente no hace nada.

La primera vez que usas un depurador de verdad en lugar de console.log, se siente como tener un superpoder. Ves todas las variables del ámbito sin tener que decidir de antemano qué imprimir. Puedes recorrer los condicionales paso a paso y ver qué rama se ejecuta. Cazar un bug complicado pasa de minutos a segundos.

Acuérdate de quitar la línea debugger antes de hacer commit, o mejor aún: pon breakpoints directamente desde DevTools haciendo clic sobre el número de línea en el panel Sources.

Trucos de DevTools que vale la pena conocer

Hay algunas funciones que la gente pasa por alto durante años:

  • Breakpoints condicionales: haz clic derecho sobre el número de línea en Sources y define una condición como user.id === 42. El breakpoint solo se dispara cuando la condición se cumple.
  • Logpoints: en el mismo menú, "Add logpoint". Imprime un mensaje sin pausar la ejecución y sin tener que tocar tu código.
  • $_ en la consola: devuelve la última expresión evaluada. Ejecuta algo y luego usa $_ para recuperarlo.
  • $0: el elemento seleccionado actualmente en el panel Elements. $0.textContent te deja inspeccionar lo que acabas de clicar.
  • Guardar como variable: haz clic derecho sobre cualquier valor en la consola y elige "Store as global variable". Te aparecerán temp1, temp2, etc., para jugar con ellos.
  • Panel Network → Copy as fetch: convierte cualquier petición en una llamada fetch() lista para pegar en la consola y modificar a tu gusto.

Ninguno es imprescindible. Pero todos te ahorran tiempo una vez que los tienes interiorizados.

Limpieza antes de subir a producción

Los console.log olvidados son inofensivos en desarrollo, pero hacen ruido en producción. Algunos hábitos que ayudan:

  • Usa una regla de lint (no-console en ESLint) para detectar logs sueltos, dejando fuera warn y error.
  • Envuelve los logs más verbosos en una comprobación: if (process.env.NODE_ENV !== "production") console.log(...).
  • Tira de console.debug para la salida de tipo traza: la mayoría de bundlers y agregadores de logs pueden filtrarla.
  • Mejor todavía: usa un pequeño módulo de logger (o una librería como debug) para poder activar y desactivar categorías de logs sin tocar el código.

Loguear no es gratis. Cada llamada serializa sus argumentos y escribe a un buffer. Dentro de un bucle caliente, un log olvidado puede ralentizar las cosas de forma medible.

Siguiente paso: expresiones regulares

Vas a depurar mucho código que procesa strings, y buena parte de ese código tira de regex — la función más compacta y, a la vez, más críptica del lenguaje. En el próximo capítulo empezamos con un recorrido tranquilo por las expresiones regulares en JavaScript y los métodos que las utilizan.

Preguntas frecuentes

¿En qué se diferencian console.log y console.dir?

console.log imprime los valores con el formato por defecto del navegador: si le pasas un elemento del DOM, te lo muestra como HTML. En cambio, console.dir siempre te enseña la vista de objeto JavaScript con todas sus propiedades, que es justo lo que necesitas cuando quieres inspeccionar las propiedades de un elemento y no su marcado.

¿Cómo depuro JavaScript en Chrome DevTools sin usar console.log?

Abre el panel Sources, busca tu archivo y haz clic en el número de línea para poner un breakpoint. Cuando la ejecución llegue ahí, se pausa y puedes inspeccionar variables, ir paso a paso y evaluar expresiones en la consola. También puedes escribir debugger; directamente en el código para forzar una pausa desde el propio fuente.

¿Cómo mido cuánto tarda en ejecutarse un trozo de código JavaScript?

Envuelve el código entre console.time('etiqueta') y console.timeEnd('etiqueta') usando la misma etiqueta en ambos. La consola te imprime el tiempo transcurrido en milisegundos. Si necesitas un análisis más detallado, tira del panel Performance de DevTools para grabar un flame chart con todo lo que se ejecutó.

¿Para qué sirve console.table?

console.table muestra arrays y objetos como una tabla ordenable en la consola, mucho más fácil de leer que un volcado de objetos anidados. Va genial con arrays de objetos: cada objeto se convierte en una fila y sus claves pasan a ser columnas. Además, puedes pasarle un segundo argumento para indicar qué columnas quieres ver.

Aprende a programar con Coddy

COMENZAR