Seleccionar página

En el día a día del desarrollo con Javascript nos encontramos muy a menudo utilizando console. Es una navaja multiusos que nos facilita la vida a la hora de depurar nuestro código. La mayoría de nosotros ha utilizado algún que otro console.log(), pero tiene bastantes otras utilidades que sería interesante conocer y sacarles partido.

Hay que hacer una advertencia previa: console no es parte de la especificación de Javascript, es un objeto global facilitado por los navegadores y por Node. Se ha estandarizado su uso y todos los navegadores modernos tienen sus principales funcionalidades. Lo cierto es que hay algunas diferencias en la implementación de algunas funcionalidades, pero realmente no son críticas y podemos usar la mayoría de ellas sin preocuparnos demasiado. Detallaremos algunas diferencias entre los navegadores y Node, ya que la consola de unos y otro son bastante diferentes.

Mensajes

El primer objetivo del API de console es mostrar mensajes en consola, es seguramente el uso más habitual que le hacemos con console.log(). Lo que quizás no sepas es que podemos diferenciar el nivel de nuestro mensaje por medio de:

  • console.info(): muestra un mensaje de nivel de información. Normalmente se mostrará en azul, aunque en Node no se diferencia de console.log().
  • console.log(): muestra un mensaje de nivel de depuración. Antes también estaba disponible un console.debug(), pero se considera que es una funcionalidad en desuso y debe utilizarse console.log().
  • console.warn(): muestra un mensaje de nivel aviso. Normalmente se mostrará en naranja, aunque en Node no se diferencia de console.error().
  • console.error(): muestra un mensaje de nivel error. Normalmente se mostrará en rojo.
console.info(  'Este es un mensaje de información' );
console.log(   'Este es un mensaje depuración'     );
console.warn(  'Este es un mensaje de aviso'       );
console.error( 'Este es un mensaje de error'       );

Formato de los mensajes

Es muy posible que estemos concatenando cadenas para construir los mensajes que enviamos a consola, o que incluso utilicemos las plantillas de texto de ES6 para componer los mensajes, pero console ofrece dos mecanismos propios para concatenar contenido.

Cualquier de los métodos de escritura de mensajes acepta múltiples valores separados por comas. Estos valores se imprimen en consola seguidos unos tras otros y añadiendo un espacio en blanco entre ellos. Es una solución bastante sencilla de utilizar y servirá en la mayoría de los casos.

var msg = "Mensaje que queremos imprimir";
console.info('[', new Date().toISOString(), ']', 'INFO', msg);

También es posible utilizar console con un primer parámetro que es texto con sentencias de escape que empiezan por % y el resto de parámetros son los valores que deben situarse en las diferentes sentencias de escape según el orden en el que aparecen. Las expresiones de escape más habitualmente aceptadas son:

  • %s: cadena de texgto.
  • %d: numero entero (en Node soporta también de coma flotante).
  • %f: número de coma flotante (no es soportado por Node)
  • %o: muestra un objeto que se puede analizar en la consola (sólo soportado en los navegadores)
  • %j: objeto con format JSON (sólo soportado en Node).
  • %%: Permite mostrar un signo %.
var msg = "Mensaje que queremos imprimir";
console.info('[%s] INFO "%s"', new Date().toISOString(), msg);

Mostrar datos complejos

Si necesitamos mostrar un objeto o una matriz, nos encontraremos en bastantes ocasiones que la impresión en consola con los métodos anteriores no es del todo satisfactoria, para resolver esta situación disponemos de:

  • console.dir(): permite mostrar el contenido de un objeto con detalle. Se mostrará de forma diferente si estamos en un navegador (su consola permite una inspección en cascada) o en Node (donde se convertirá a una cadena JSON).
var obj = {
    num: 1,
    text: "text",
    sub: {
        arr: [1,2,3],
        non: null
    }
};
  • console.table(): con este método podemos mostrar en forma de tabla una matriz que contenga otras matrices. Es útil para mostrar algunos datos estructurados, aunque no está disponible en Node de forma nativa, pero sí en la mayoría de los navegadores. Si queremos usarla en Node deberemos utilizar algún paquete como better-console.
var data = [
    [1, 2, 3],
    [1.0, 2.0, 3.0],
    ['uno', 'dos', 'tres'],
    ['.', '..', '...']
];
console.table(data);

Medición del tiempo de ejecución

Otras de las capacidades interesantes es console es medir el tiempo transcurrido entre la ejecución entre dos instrucciones. Aunque su precisión no es extremadamente alta si ejecutamos unas pocas líneas, es de mucha utilidad para comprobar el rendimiento de nuestro código en general e identificar algunos cuellos de botella.

  • console.time([identificador]): empieza a contar el tiempo. Se le puede pasar un parámetro para tener varios cronómetros a la vez.
  • console.timeEnd([identificador]): termina de contar el tiempo y muestra el resultado en la consola. Si le pasamos el identificador cerraremos ese cronómetro en concreto, manteniéndose el resto.
const LOOPS = 1000000;

console.time('for');
var data1 = new Array(LOOPS);
for (let n = 0; n < LOOPS; n++) {
    data1[n] = Math.random();
}
console.timeEnd('for');

console.time('map');
var data2 = new Array(LOOPS);
data2 = data2.map(function() {
    return Math.random();
});
console.timeEnd('map');

Pila de llamadas

Si queremos mostrar las pilas de llamadas en la consola podemos utilizar console.trace(). Mostrará las diferentes funciones que se han ido llamando hasta llegar a la instrucción.

function a() {
    return b();
}
function b() {
    return c();
}
function c() {
    console.trace();
}
a();

Assert

Otra interesante característica es console.assert(). Este método es un assert parecido al que ofrecen muchas librerías o paquetes de pruebas, pero ya lo tenemos disponible directamente en nuestro navegador, sin necesidad de carga nada más.

  • console.assert(expresión a evaluar, [mensaje], […]): Si el primer parámetro es falso se lanzará un error y se mostrará el mensaje que se pasa a continuación, con las mismas características del resto de métodos que muestran mensajes en consola.
console.assert(true, 'No hace nada');
console.assert(false, 'Ups %s', 'algo no ha funcionado');

Cómo continuar conociendo las capacidades de console

Estas funcionalidades solo son algunas de las posibilidades de console. Por ejemplo, en Node podemos crear nuestras propias consolas heredando de Console() y también podemos establecer a que stream se envían los mensajes estándar y de error. Por otra parte, en la mayoría de los navegadores se pueden establecer grupos de avisos que se muestran colapsados en la consola.

Para profundizar sobre estas y otras funcionalidades, os recomendamos leer (en inglés):

Novedades

JSDayES en directo

Sigue en directo las charlas y talleres del impresionante JSDayES 2017. Ponentes de primer orden, tanto nacionales como internacionales, nos mostrarán todos los aspectos de Javascript. El viernes 12 de mayo de 16:00 a 21:00 y el sábado 13 de mayo de 9:30 a 21:00 (hora de Madrid).

The CITGM Diaries by Myles Borins [video]

Myles Borins de Google, miembro del CTC de Node.js (Node.js Core Technical Committee), nos cuenta (en inglés, por supuesto) como funciona CITGM (Canary In The Gold Mine), una herramienta que permite obtener un módulo de NPM y probarlo usando una versión específica de NodeJS.

Debate: Tecnologías de Front Web [vídeo]

Desde las principales comunidades de desarrollo de tecnologías de front (Madrid JS, Polymer Madrid, Angular Madrid y VueJS Madrid) se ha organizado este debate que pretende ser un ejercicio de sentido común en relación a las tecnologías de front actuales centradas en componentes.

breves

Matrices dispersas o sparse arrays en JS

Una característica que puede producir algunos problemas, si no lo tenemos en cuenta, es la posibilidad de tener matrices con huecos, es decir, con algunos de sus elementos sin definir. Es lo que se suele denominar una matriz dispersa o sparse array. Veamos cómo trabajar con esta características de las matrices.

Algunos operadores de bits usados con asiduidad

Cada día más a menudo podemos encontrar operadores binarios utilizados como formas abreviadas de algunas operaciones que de otra forma sería algo menos compactas y, quizás, más comprensibles. Veamos algunos casos en detalle.

Cómo diferenciar arrow function de function

En un reciente artículo Javier Vélez Reyes hace patente las principales diferencias entre las funciones tradicionales y las funciones flecha, ya que ambos modelos no son equivalentes e intercambiables. Veamos cómo es posible saber si una función ha sido construida por medio de la instrucción function o como una arrow function.

Obtener todas las propiedades de un objeto

¿Cómo podemos obtener absolutamente todas las propiedades de un objeto? No disponemos de un método nativo para este propósito, pero en unas pocas lineas podemos construir una función para nuestro propósito.