Javascript Debugging
With tools like the Chrome and FireFox developer tools JavaScript debugging is much easier. There are many times when you still need to log statements to the console. This is a quick post on how to log to the console like a JavaScript pro. Console logging deserves its own post.
console.log()
Let’s consider three different values each assigned to their own variables. Many JS developers typically log output like this:
let name = "Daz";
let nickName = "Show bags";
let age = "40";
console.log(name);
console.log(nickName);
console.log(age);
Which will output:
Daz
Show Bags
40
Alternatively, this could be simplified to:
let name = "Daz";
let nickName = "Show bags";
let age = "40";
console.log(name, nickName, age);
Which will output:
Daz Show Bags 40
These two variations of the same are simple and effective. However neither method tells us which output corresponds to which variables. When dealing with many variables this can be confusing.
Let’s improve this to what I would say is a better way to log these variables by using computed property names.:
let name = "Shaz";
let nickName = "Cyclone";
let age = "24";
console.log({name, nickName, age});
Which will output:
{name: "Shaz", nickName: "Cyclone", age: "24"}
Better? By simply wrapping our variables in curly brackets inside the console log we have made use of JavaScript’s ability to compute property names. This has effectively reduced our code footprint and improved the output to be clearer and more meaningful.
Formatting console.log() output
I don’t use this too much but console.log()
statements can be formatted with CSS? Let’s say you have an output that you would like to draw attention to. Try this:
let name = "Bazza";
let nickName = "Pothole";
let age = "32";
console.log("%c Outputting a mate", "color: green; font-weight: bold;");
console.log({name, nickName, age});
Try it! This can be a helpful visual cue when you have a lot of console output.
Outputting an array of objects using console.table()
Most developers have sifted through an array of objects inside the browser console looking for a specific item. It’s frustrating, error prone and not very fast.
console.table()
to the rescue! Compare the two outputs from the following log statements.
let mates = [
{
name: "Maz",
nickName: "Ferret",
age: 37
},
{
name: "Wozza",
nickName: "Skinny legs",
age: 21
},
{
name: "Micka",
nickName: "Plover",
age: 46
},
]
console.log(mates);
This will output:
0: {name: "Maz", nickName: "Ferret", age: 37}
1: {name: "Wozza", nickName: "Skinny legs", age: 21}
2: {name: "Micka", nickName: "Plover", age: 46}
This is a basic example so it it’s easy to navigate through the objecs. Consider when you have many (let’s say 20+) more complex objects. It doesn’t take much imagination to see that this could become quite slow to read. With this in mind, let’s make a simple improvement that will greatly improve our ability to read the logged output. We will replace the console.log()
with a console.table()
statement like this:
// replace console.log(mates) with:
console.table(mates);
Instantly the console output is improved to include both a table of the objects and the raw object output:
|(index) |name |nickName |age| |:——|:——|:————|:—| |0 |”Maz” |”Ferret” |37 | |1 |”Wozza”|”Skinny legs”|21 | |2 |”Micka”|”Plover” |46 |
0: {name: "Maz", nickName: "Ferret", age: 37}
1: {name: "Wozza", nickName: "Skinny legs", age: 21}
2: {name: "Micka", nickName: "Plover", age: 46}
So simple yet so effective!
Logging performance with console.time()
Sometimes you may need to determine how fast a block of code runs. With console.time()
this is pretty easy.
console.time("MyTimer");
// do something here. For example:
for (let i = 0; i < 1000; i++)
console.log("Melbourne rules OK!");
console.timeEnd("MyTimer");
Which will output:
MyTimer: 78.428955078125ms
Wrap your code in named timers can be a handy tool for identifying performance bottlenecks.
console.trace()
- leaving the best until last
Little known but powerful, console.trace()
can help debug your application by logging to the console the call stack up to the point where console.trace()
was called. That is, it reports what functions have been called to get to the point where it was called. In a large application with many functions and many files this is a powerful debugging tool. Especially when a function is called in multiple places throughout the code base. Without it, developers tend to litter their code with multiple log statements. console.trace()
is easier, more concise and gives better output.
1. function tracing(){
2. function start(){
3. let x = 100;
4. let y = 23;
5. return sum(x, y);
6. }
7.
8. function sum(x, y){
9. console.trace("Tracing to here!");
10. return x + y;
11. }
12. return start();
13. }
14. let sum = tracing();
15. console.log(sum);
This will output:
Tracing to here!
sum @ VM512:9
start @ VM512:5
tracing @ VM512:12
(anonymous) @ VM512:14
If you follow the output you can step through the stack call from the console.trace()
statement until the call to the tracing() statement on line 14. This is so powerful for debugging complex applications and it can be much faster than using a debugger.
Note: The global namespace is an unnamed function in JavaScript. Explains the anonymous function at the end of the output.
Note 2: I’ve run this example directly in the JavaScript console. If you were running this from a .js
file you would also have the filename in the output. Handy!
Conclusion
In this quick post I’ve covered a number of handy console
API functions that you can easily use to improve your debugging capabilities. The best part is that they are all simple whilst allowing you to develop faster.
Reading more
Console API on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Console
« Team Building in a Hot Market
»