Beyond console.log - you can do more!
Most web developers and I am sure every javascript developer knows how to print messages to the console, using console.log
in the browser.
It is the easiest way to get information about the code and helps the developers, when they are debugging a problem and don’t want to use the debugger
because they don’t want to dive too deep into a framework like Vue.js or have any other reason.
But there is more than the console.log
command and in this article we will look at these other options.
console.log()
Let’s start with the basics. Everyone knows that you can use the log
function to print out strings, objects and arrays.
Here is a short example for the output (Foo is a string, user an object and books an array):
console.log('Foo', user, books);
But you can even do more with the log
function.
First there is the possibility to return a formatted string.
Either with a simple string concatenation or with some kind of sprintf
function as known from PHP.
console.log('I like the ' + user.job + ' ' + user.short + ' very much.');
console.log('I like the %s %s very much.', user.job, user.short);
If you choose %o
instead of %s
, you can use a object as placeholder. And if you want, you can even use css with the %c
placeholder.
Here is a short example, but I’ve never needed this case before.😅
console.log('I am a placeholder for %cCSS', 'color: orange; background-color: black; padding: 2px 5px; border-radius: 2px');
console.dir()
For the most part, the dir()
function is very much like log()
, though it looks a little bit different.
Things get more interesting when you select an element and look at the result.
With the log()
output, we get the children of the DOM-Element we have selected.
With dir()
we get an interactive listing of the properties about the HTML-Element, which may be useful from time to time.
Information levels
console.info
, console.warn
and console.eror
are the three information levels the console contains.
You can use them to weight the information in an application differently.
console.info('Hello World');
console.warn('Hello World');
console.error('Hello World');
console.group()
With the group()
function it becomes really simple to properly organize
related data and represent each group with a definitive label. The label always remains optional.
To close the group, there is the function groupEnd()
.
console.group('Levels');
console.group(); // No label
console.info('Hello, I am an info');
console.group('Warning');
console.warn('Hello, I am a warning');
console.group('Error');
console.error('And I am an error');
console.groupEnd();
console.groupEnd();
console.groupEnd();
console.groupEnd();
console.log('All groups closed');
We don’t have to pass the name to the groupEnd()
function, because it will always close the recently created group.
Groups created by group()
are initially opened.
In case you want the group to appear collapsed just use groupCollapsed()
.
console.clear()
Sometimes there is just way too much information in the console and also a lot of bullshit from extensions or old bugs that don’t interest us anymore. To get a usable console again, you can empty the console with the clear command.
console.clear();
Be aware if the preserve log
option is active, this command does not work.
console.table()
With the the table()
function you can display tabular data in a way that’s much neater than just dumping out the object.
console.log(data);
console.table(data);
console.assert()
Console.assert is my personal favourite. This function is used to run simple assertion. It needs two required arguments, the first one is is the expression
which should be truthy
or falsy
.
The second argument is the message
you want to print. But the message is only printed, if the expressions is falsy.
Using this function, you don’t need to write a if
-condition, to show the message.
Console.assert saves me so much time, it’s easy to use, but it’s damn useful to hunt nasty bugs. I recommend to try out this function, unless you already use it of course.
console.assert(5 > 10, 'This is bullshit, so we get a message.');
console.assert(10 > 5, 'This is correct, so we do not see the message.');
console.count()
This function is used to set a counter of how many times a particular string gets logged in the console. The first argument is an optional label, which can be used to have a named counter. If no label is given, the label is the given string.
console.count('foo', 'some-string');
console.count('no-label');
console.count('foo', 'some-string');
console.count('foo', 'some-string');
console.countReset('foo');
console.count('foo', 'some-string');
Consider, this this function only works with strings and can currently not distinguish between different objects.
If you want to reset the the counter use the
countReset()
function.
console.time()
The time()
function starts a timer that can be used to compute the duration of an operation. This timer can be stopped with timeEnd()
, additionally timeEnd()
prints the total time in milliseconds to the console.
Timers can be identified by a given label. If no label is given the timeEnd
will stop the most recent time function.
You can use this function if you need to check the performance of a piece of code.
This method is much more accurate than to write date.now
at the start and end to the console and then calculate the difference.
console.time();
let sum = 0;
for (let i = 0; i < 1000; i += 1) {
sum += i;
}
console.timeEnd();
// Output
default: 0.0283203125ms
console.profile()
I recently discovered this feature for myself when I started working on performance optimizations for one of my applications.
With the profile()
function you can record a performance profile of the CPU and memory usage where it is called.
You can give the profile an optional name and find the recording in the JavaScript Profiler
tab. If you don’t see the tab, you have to go to more tools in the settings and select the JavaScript Profiler
.
To end the recoding use the profileEnd()
function.
I am sorry, I couldn’t come up with a simple and realy usefull example, but I hope you get the idea behind this function.
console.profile('simple example');
let sum = 0;
for (let i = 0; i < 100000; i += 1) {
sum += i;
}
console.profileEnd('simple example');
// Output
Profile 'simple example' started.
Profile 'simple example' finished.
console.trace()
Sometimes, while debugging a complex problem we get stuck in the dead end of detecting the problem because a function is called too many times and we don’t know where the issue comes from.
Imagine you have a validation service that is called in different components or even by other services. And one of these calls results in an error, but the default error message only tells you that the error is in the service.
This message is not necessarily helpful. But now we want to find out which consumer produces this error. This is exactly the time when you can use the trace()
function.
function isGreaterThan(a, b) {
console.trace();
return a > b;
}
function callGreater() {
this.isGreaterThan(4, 2);
}
function traceExample() {
this.isGreaterThan(10, 5);
this.callGreater();
this.isGreaterThan(undefined, 3);
}
traceExample();
console.memory
If you have an even more sneaky problem, for example you have a tricky lack of memory you could check your memory heap size status.
Therefor, you use the meomory
property of the console
, yeah - this is just a porperty and not a function.
console.memory
//Output
MemoryInfo {
totalJSHeapSize: 10000000,
usedJSHeapSize: 10000000,
jsHeapSizeLimit: 3760000000,
}
Wrapping it up
The console is a pretty powerful tool for a web developer. It offers so much more than just the log function, so try to include one of these other functions in your debugging process, it can really save a lot of time and even nerves at the end of the day.