Rindiendo un poco de tributo al primer post publicado en fernetjs, se me ocurrió que este tema podría resultar interesante.

El objeto console es una interface para comunicarnos por código con la consola, que hoy en día viene incluída por defecto en la mayoría de los navegadores como parte de las herramientas para el desarrollador. Si bien no existe un estándar para esta API, es implementada por la mayoría de los navegadores y otras plataformas como Node.js de manera bastante consistente.

Muchos recordaremos los errores que nos daba internet explorer <= 8 cuando nos olvidábamos un console.log en el código o no implementábamos el objeto console nosotros mismos. Por suerte, en líneas generales, esto es cosa del pasado!

Como siempre recomiendo abrir la consola y empezar a probar cosas, nada más útil que eso. Espero que al terminar de ver esto, alguien tenga más herramientas para depurar de manera más efectiva y creativa sus programas.

debug, log, info, warn y error

log es el método más conocido, escribe a la consola lo que le pasamos como parámetro.
info, warn y error funcionan de la misma manera que log, aunque la salida en consola es estéticamente diferente (generalmente tiene un ícono, y un color diferente). Obviamente la mayor diferencia es su significado, y que desde la consola podemos filtrar por nivel de logueo.
debug() es solamente un alias para log(), y se desalienta su uso, ya que existe solo para mantener compatibilidad hacia atrás.

console.log('Esto va a salir por consola');
console.info('Qué ganas de tomar un fernet!');
console.warn('El fernet está muy caro');
console.error('No me alcanza pal fernet');

log info warn y error

Todos estos métodos soportan que le pasemos varios parámetros.

// no hace falta hacer
console.log('Este es el título de mi documento: ' + window.document.title);
// puedo hacer
console.log('Este es el título de mi documento:', window.document.title);

También se soporta el uso de “templated strings”. Como primer parámetro podemos pasar un string que contiene “strings de reemplazo”, que van a ser el lugar donde se van a formatear los sucesivos parámetros restantes.

var stock = 1,
  marca = 'acme';
console.warn('Me queda %d fernet marca %s :(', stock, marca);
// imprime: 'Me queda 1 fernet marca acme :('

Pueden existir diferencias entre navegadores, pero en general los posibles strings de reemplazo como %s son:

%s formatea el valor como un string.
%d o %i formatea el valor como un número entero.
%f formatea el valor como un número de punto flotante.
%o formatea el valor como un elemento DOM expandible (como en el tab de elements de las devtools, pasando el mouse por encima resalta el elemento en el documento según corresponda).
%O formatea el valor como un objeto de JavaScript expandible.

log con %O
log con %o

Adicionalmente, se puede formatear la salida con CSS, utilizando %c. El soporte para estos estilos también puede cambiar en base al navegador.

console.log('%cFERNETJS', 'background:#AAAA00; font-size:16pt');

console log con estilo

Utilizando las características vistas hasta ahora, ya se pueden hacer bastantes cosas, que inclusive van más allá del debugging. Por ejemplo, muchas empresas han colocado mensajes en la consola para reclutar desarrolladores usando estilos y arte ascii, y algunos hasta han ido más allá haciendo juegos!

assert

console.assert es muy similar a console.log, con la diferencia de que solo escribe el mensaje en consola sólo cuando el primer parámetro es falso, y lo acompaña con el stacktrace.
Es muy útil para todas aquellas situaciones en las que no queremos “spammear” la consola o queremos detectar situaciones no esperadas, por ejemplo dentro de un game loop.

console.assert(true, 'Esto no va a imprimir nada en consola');
console.assert(false, 'Esto si');

function sum(a, b){
  console.assert(typeof a === 'number', 'a no es un número!:', a);
  console.assert(typeof b === 'number', 'b no es un número!:', b);
  return a + b;
}

sum(1,2); // no imprime nada en consola
sum(10, '???'); // Assertion failed: b no es un número!: ???
// de todas maneras retorna '10???'

count

console.count loguea en consola la cantidad de veces que esta línea es llamada. Recibe solamente un string como parámetro, que es la etiqueta a utilizar para este contador.

function load(){
  // [...]
  console.count('load');
}
function render(){
  // mucho código aquí
  console.count('render');
}
load(); //load: 1
render(); //render: 1
render(); //render: 2

dir

Recibe un objeto como parámetro, y lo representa en consola de forma interactiva, pudiendo explorar sus propiedades, tal como vimos anteriormente, como si hicieramos console.log('%O', window);

table

console.table recibe un objeto o array y lo representa en forma de tabla en la consola. También puede recibir un último parámetro que es un array de strings que contiene las propiedades que se quieren incluir. Inclusive se puede ordenar por columna clickeando en el encabezado de la tabla!

var links = [
  { nombre: 'MDN', url: 'https://developer.mozilla.org/en-US/docs/Web/API/Console.table'},
  { nombre: 'npmPackage', url: 'https://www.npmjs.org/package/console.table'}
];
console.table(links);

// sólo nos interesa la propiedad url
console.table(links, ['url']);

// podemos imprimir objetos
var linksComoObjetos = {
  MDN: {
    url: 'https://developer.mozilla.org/en-US/docs/Web/API/Console.table'
  },
  npmPackage: {
    url: 'https://www.npmjs.org/package/console.table'
  }
};
console.table(linksComoObjetos);

Los ejemplos son bastantes triviales, pero puede a llegar a ser bastante útil y cómodo. Por ejemplo, qué pasa si hacemos console.table(console) ?

group, groupCollapsed y groupEnd

Son métodos que nos permiten tener organizado todo el logueo que hagamos a la consola. Nos permiten agrupar por funcionalidad común o por el criterio que nosotros elijamos.

Primero llamamos a console.group con una etiqueta, y todo logueo de consola que se haga después de eso, va a quedar agrupado dentro de la misma hasta que llamemos a console.groupEnd con la misma etiqueta. console.groupCollapsed es idéntico a console.group, salvo que por defecto ese grupo arranca sin estar expandido en la consola.

function update(){
  for(var i=0; i< 5; i++){
    console.log(i);
  }
  console.count('update');
}

function render(){
  console.warn('render');
}


console.group('logica');
update();
console.groupEnd('logica');
console.groupCollapsed('rendering');
render();
console.groupEnd('rendering');

También se pueden tener grupos anidados!

function update(){
  console.groupCollapsed('DB');
  for(var i=0; i< 5; i++){
    console.log(i);
  }
  console.groupEnd('DB');
  console.count('update');
}

function render(){
  console.warn('render');
}


console.group('logica');
update();
console.groupEnd('logica');
console.groupCollapsed('rendering');
render();
console.groupEnd('rendering');

trace

console.trace muestra en consola el stacktrace (pila de llamadas) correspondiente. Dependiendo del browser se le puede pasar como parámetro un string que va a ser el nombre que podemos utilizar para identificarlo.

time, timeEnd

De manera similar a group y groupEnd, reciben una etiqueta como parámetro. Al llamar a console.time('etiqueta'), un timer comienza a correr para esa etiqueta, que parará cuando se llame a console.timeEnd('etiqueta'), y se imprimirá el tiempo en pantalla.

console.time('ejemplo poco original');
setTimeout(function(){
  console.timeEnd('ejemplo poco original');
}, 1000);
// en consola se logueará algo similar a:
// ejemplo poco original: 1843.323ms
// estará muy lenta mi máquina, que arroja ese número considerablemente más grande que 1000ms!

profile, profileEnd

Esta funcionalidad no está disponible en todos los browsers, o por lo menos solo está documentada en chrome, firebug, e IE.
Al llamar a profile, se arranca una sesión de profiling, hasta que se llama a profileEnd. Opcionalmente se puede llamar con una etiqueta, y sería equivalente a arrancar y terminar la sesión manualmente desde las dev tools. Más allá de la llamada a console.profile, el tab de profiling puede ser determinante para encontrar problemas de performance en tu código!


console en Node.js

En node console también está disponible. Para ver sus métodos, recomiendo ir a la documentación. Pero haciéndola corta, los métodos implementados son log, info, error, warn, dir, time, timeEnd, trace y assert.
Como en node todo el resultado del logging va a ir a algún stream (stdout o stderr por defecto), no tenemos “chiches” interactivos como sucede con los browsers. Tampoco una acumulación de utilidades diversas, por la filosofía que node sostiene, pero estoy seguro que sea lo que quieras hacer, ya hay un módulo para eso.

Referencias externas:
MDN
Chrome
MSDN
Opera