Monday, 23 January, 2017 UTC


Summary

Many JavaScript developers only use the console.log statement for the purpose of finding out more about how their application works. In this article, you will learn that the console API contains many powerful methods that will significantly improve your logging and debugging experience.
In this article, we will focus on browser features. Although you can use some of them in node, many console methods only work in the browser.

console.time

Let’s create an array of 100.000 random numbers.
arr = new Array(100000).fill( null ).map( () => Math.random() )
We can measure time taken to sort the array by placing the sort operation between console.time and console.timeEnd. You can also add a label to these console operations to know what you are measuring exactly:
console.time( 'sort' );
arr.sort();
console.timeEnd( 'sort' );
> sort: 305.588ms
Notice that for more reliable results, the measurement has to be repeated multiple times. The conditions under which measurements are executed also matter, as you will get slower results in an environment with memory leaks.
Timers also work in web workers.

console.table

My personal favorite for displaying arrays of objects or objects of objects. This console method is great for debugging, as you can observe all values your array or object as a two dimensional table.
let matrix = new Array(5)
    .fill( null )
    .map( () => [...'0123456789'] );
console.table( matrix );
console.table in action
Don’t expect console.table to work in the node environment.

Log, info, warn, error

Most developers already know how console.log works. In practice though, I can see console.log often overused, not taking other severity levels into consideration.
Console log, info, warn, and error
Notice the count of warnings and error messages on the top right of the image. Warnings are less severe than errors. Developers may choose to ignore warnings, while errors have to be dealt with. Always respect the severity level of the log messages, and adjust your messages accordingly.
Different messages are used for different purposes.
Make sure you don’t forget about the anomalies of logging reference types. Recall the following code segment:
var wallets = [{ amount: 0 }];

setInterval( function() { 
    console.log( wallets, wallets[0], wallets[0].amount ); 
    wallets[0].amount += 100; 
}, 1000 );
If you execute this code in the console, and open different console logged objects, you will realize that the wallet amount always reflects the amount at the time of first opening the logged object.

console.trace

You don’t have to use console.error to print the stack trace at any given point in the execution of your code.
The trace method prints the stack trace to the console without highlighting it as an error.
In the below example, recursive error returns undefined. The function recursively calls itself until reaching 0. As soon as 0 is reached, the console.trace command is executed, printing the stack trace to the console.
let recursiveError = x => x > 0 ? recursiveError( x - 1 ) : console.trace('abc'); 

recursiveError( 3 )

VM1292:1 abc
recursiveError @ VM1292:1
recursiveError @ VM1292:1
recursiveError @ VM1292:1
recursiveError @ VM1292:1
(anonymous) @ VM1326:1

> undefined

console.count

The console.count method displays the number of times it was called. An optional label can be added to display what we are counting.
let swap = function(arr, i, j) {
    console.count( 'swap' );
    [ arr[i], arr[j] ] = [ arr[j], arr[i] ];
}

let bubbleSort = function( arr ) {
    let hasSwapped = false;
    do {
        hasSwapped = false;
        for ( let i = 0; i < arr.length - 1; ++i ) {
            if ( arr[i] > arr[i+1] ) {
                swap( arr, i, i+1 );
                hasSwapped = true;
            }
        }
    } while ( hasSwapped );
} 

let arr = [ 5, 4, 3, 2, 1];


bubbleSort( arr )
> swap: 1
> swap: 2
> swap: 3
> swap: 4
> swap: 5
> swap: 6

console.assert

Assertions are expressions evaluated as truthy or falsy. When an assertion is truthy, nothing appears on the console. Assertions succeed silently.
When an assertion is falsy, an error appears on the console. Note that in node, an error is also thrown after the first failed assertion, terminating execution of your code. In the browser console, execution of your code is continued:
Console assertions
Notice that failed assertions result in an error, but execution of the code continued with the info message in the line after the error. When an assertion is true, the line of the assertion is ignored, nothing is printed to the console.
Assertions are normally used during development for making sure that your code is executed in a specific way. During writing automated tests, assertion libraries such as ChaiJs are used.

console.group

The last method is just a stylistic addition, grouping any of the above console statements in indentation levels. Obviously, grouping only affects the web console.
Outputs of console statements are indented inside a group determined by the console.group and console.groupEnd statements.
Console Group

Summary

The JavaScript console API is a lot more complex than just a logger. The more you use these methods, the easier you will understand the logged messages, resulting in a lower overall time spent on finding the root cause of a bug.
The code examples of this course were written in ES6. If you like these examples, sign up for my ES6 course below.
Learn ES6 in Practice
Sign up below to access an ES6 course with many exercises and reference solutions.