Another trick that might be more practical for actually debugging is using the object shorthand. For example, instead of...<p><pre><code> console.log(x, y);
</code></pre>
which contains the information you need, but lacks any useful context, try...<p><pre><code> console.log({x, y});
</code></pre>
...which will print out like an object, including the key names.
I've put over 200 tips like that on my website: <a href="https://umaar.com/dev-tips/" rel="nofollow">https://umaar.com/dev-tips/</a><p>Each tip has a textual explanation, and an animated gif if you're a visual learner (I know, I need to scrap gifs and move to regular videos).<p>There's a lot of tricks there which can hopefully improve your development and debugging workflows. Let me know if there are specific things you'd like to see. A few people have asked for how to find memory leaks.
Wow there are some cool tricks here!<p>In Firefox any objects you pass to console.log are expandable, so you can say console.log("my hash", h). It seems to behave the same when you say console.log("my hash %o", h).<p>But there is a tricky thing that has really confused me in some debugging efforts: when expanded, the object display is "live", so it always shows the <i>current</i> properties of the object, not the properties as they were when you printed them. But the unexpanded view shows them as they were. So for example:<p><pre><code> h = {foo: "bar"}
console.log(h)
▶ Object { foo: "bar" }
h.foo = "BAR"
</code></pre>
Then you click the triangle and you see:<p><pre><code> ▼ {..}
| foo: "BAR"
| ▶ <prototype>: Object { .. }
</code></pre>
I don't know if that's a bug or desired behavior, but watch out for it! In the past I've used console.log(JSON.stringify(h)) to capture the full object as-is. I guess turning it back into an object would be even nicer, so you could have a deep copy to navigate.
My whole personal site[1] is one big console.log(), right down to theme matching :D Unfortunately I'm not sure anyone has actually noticed.<p>1: <a href="https://itsokayitsofficial.io/" rel="nofollow">https://itsokayitsofficial.io/</a>
If you're using console.log to do debugging then it's worthwhile giving yourself a little more data to point at where a problem might lie - timings.<p>Open up devtools (cmd+option+j), then open the command palette (cmd+shift+P), and then search for "console", and then select "Console - Show Timestamps". Now every console output will have the high definition timestamp prepended to it. That can be really helpful if you don't want to go down the whole perf chart rabbit hole, or if you think things might be running in the wrong order due to some async weirdness.<p>(This probably only works in Chrome)
All that text and no links to the reference docs to allow one to learn to fish and also learn about changes in the future: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console" rel="nofollow">https://developer.mozilla.org/en-US/docs/Web/API/Console</a>
Let me save someone a few minutes of confusion: generally I use console.table instead of console.dir ever since I discovered console.dir is basically unpredictable. Try using it on an Error or anything that inherits from Error and you'll see it puts out what looks like an expandable stack trace. I have no idea how or why it's implemented to do that, but basically it just varies from one object to the next and I dislike that.
Since I don’t see it mentioned yet: my favorite thing to do if I’m console slumming is to use it as a comma-separated expression. You can use console.log(), foo as a single expression (eg as an arrow function return) the log is executed but its undefined return value discarded. This saves a lot of keystrokes where you’d otherwise have to wrap the function body in braces with an explicit return statement.
My (newly discovered) favorite trick is using the comma operator. Using it, you can (admittedly horribly) log anything in the middle of any expression.<p>This for example will call `console.log(myVar)` and still call `someFunction(myVar, someOtherArgument)`.<p><pre><code> myVar = "12345"
someFunction((console.log(myVar), myVar), someOtherArgument);
</code></pre>
Pretty handy sometimes :)
Another little trick; instead of doing:<p><pre><code> console.log("some label: " + JSON.stringify(someObj))
</code></pre>
pass it as a separate parameter:<p><pre><code> console.log("some label: ", someObj)
</code></pre>
and you'll get interactive expansions/manipulation in the console
One missing mention is `console.groupCollapsed(label)` which is handy for nesting large dumps of data that you don't want to steal visual real estate.<p>Eg:
console.groupCollapsed('data$ at load');
console.groupCollapsed('GridData'); console.table(data$.GridData.toList());
console.groupEnd();
console.groupCollapsed('Loads'); console.table(data$.Loads.toList());
console.groupEnd();
console.groupCollapsed('Drv'); console.table(data$.Drv.toList());
console.groupEnd();
console.groupEnd();<p>This will present `> data$ at load` and clicking on the chevron will open the data showing the list of entries and clicking on their chevrons will show the table for each.
> Using console.log() for JavaScript debugging is the most common practice among developers. But, there is more…<p>Cut your debugging time, knowledge of console.log, and mental churn in half and set up your tooling to use a `debugger` statement. The console.log method may be used heavily but it’s actually a bad practice and often leaves code littered with log statements. Even for the purpose of logging itself you should use a logging library for serious development.<p>You should use a debugger in every language you can for development.<p>Neat tricks though.
Console.group is one of my favorite features but Chrome does not handle filtering it very well. Basically, if you want to filter on a certain term, all the groups will remain, even if nothing from those groups (title, subfields, otherwise) matches. There has been a Chromium bug open since 2014: <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=363796" rel="nofollow">https://bugs.chromium.org/p/chromium/issues/detail?id=363796</a>
I use the console.dir method occasionally to get the public methods and properties of HTML elements, for instance console.dir(document.body) would output all the methods and properties
Sometimes you wanna see the value of a variable but it's inside a hot function and ends up spamming/freezing your console if you log it.<p>Not quite a console.log statement, but Live Expression in DevTools is pretty useful for that. It's the little "eye" next to filter at the top, and it'll constantly watch an expression and show the latest value. Worst case you can assign your value to `window.myValue` and put a watch on that.
console.log can also be styled! It's a restricted subset of css so you have to hack around it, but it's good enough to make images display:<p><pre><code> img = $$('img')[0];
// console.log(img);
console.log("%cPlaceholder", `background:url("${img.src}") no-repeat cyan; border:1px solid black; padding:${img.naturalHeight}px ${img.naturalWidth}px 0 0; font-size:0; line-height:0;`);
</code></pre>
If you paste this you should see the HN logo display in your console. Credit for the image trick goes to <a href="https://github.com/adriancooney/console.image" rel="nofollow">https://github.com/adriancooney/console.image</a><p>I use this a lot for working with animated canvases. Appending the current frame into the page is not the same since you lose the context you get from being interleaved with your other log messages.
Very important for backend is %j (e.g.: console.log('%j', variable); which can output complex json objects to the terminal. I often write it to the terminal and then copy it to an online json viewer so it is formatted in a viewable format.
Is there any way to add logging that is stripped at build time? Like in C# if I have a “Debug.WriteLine” it doesn’t exist if built in release mode. I now build ts to js with a “dev” config, could that not strip out all console.debug for me?
This brings to light an issue I have encountered recently which has caused me to rely on console.log more than I would like.<p>In a recent project I have started using async/await, and seem to have lost the ability to use the debugger effectively. Breakpoints no longer seem to work properly. Its a huge negative, and im thinking of rewriting a lot of the code to remove async/await if I cant fix this issue.<p>Has anyone experienced this? If so, is there a way to fix it, or is this what I can expect when using async/await?
You can get the same behavior as console.log() without cluttering up your code by using LogPoints.<p><a href="https://developer.chrome.com/blog/new-in-devtools-73/" rel="nofollow">https://developer.chrome.com/blog/new-in-devtools-73/</a><p><a href="https://developer.mozilla.org/en-US/docs/Tools/Debugger/Set_a_logpoint" rel="nofollow">https://developer.mozilla.org/en-US/docs/Tools/Debugger/Set_...</a>
Rather than using<p><pre><code> %s, %i, %o, %f, etc.
</code></pre>
You can use a templated string, like this:<p><pre><code> `This is a string that has been printed ${someVar} times.`</code></pre>
Was reading this thinking the biggest pain is being unable to wrap console.log and keep line numbers.<p>But some Googling [1] shows that this has now been fixed by being able to blackbox your wrapper scripts.<p>[1] <a href="https://gist.github.com/paulirish/c307a5a585ddbcc17242" rel="nofollow">https://gist.github.com/paulirish/c307a5a585ddbcc17242</a>
I didn't know about .memory, .trace() and .assert(), all of which are very helpful. Up till now, I've had to add a try-throw-catch to get a stack trace and be able to follow synchronous execution flow leading up to a given function call, but console.trace will do that for me, so yay.
Would be nice to also include console.table() explained on <a href="https://phpcontrols.com/blog/debugging-javascript-go-beyond-console-log" rel="nofollow">https://phpcontrols.com/blog/debugging-javascript-go-beyond-...</a>
If I'm looking at values in node, I typically do<p><pre><code> console.dir(obj, { depth: null })
</code></pre>
However, if you need to inspect some object in a browser, don't forget you can just insert:<p><pre><code> debugger
</code></pre>
Which can be helpful at times.
Please don't add colours to your console.log statements. It might look nice in the Chrome console, but as soon as your messages end up elsewhere, in a terminal or text file for instance, it makes the statements look very messy.
Another tip I found very useful lately<p>You can use `$("selector")`, even without jQuery, in console. (not sure if with firefox, works with safari and chrome)<p>And also `$x("path")` for xpath.<p>But note, this works only in console, it’s not available from javascript.
<p><pre><code> %s – string
%i or %d – integer
%o or %O – object
%f – float
</code></pre>
Why were these ever specific types, instead of just one option that looks at the parameter type?
The ones that were new and interesting to me were towards the end:<p><pre><code> console.table(obj)
console.time('x'); console.timeEnd('x')
console.trace()</code></pre>
Didn't know about the string interpolation. Don't see a reason to use that over built in JS string interpolation (i.e. `var is ${var]`), but still interesting.
There's pro, and then there's Steven Wittens. Open the console on his site.<p><a href="http://acko.net/" rel="nofollow">http://acko.net/</a>
I think the very fact that you have to rely on things like that when debugging speaks volumes about the language deficiencies. Or maybe it's just the tooling or environments where JS is executed?<p>In any case, the debugging experience is probably the biggest reason why I dislike modern web dev and tend to steer my career towards back-end.
99% of Frontend developers don't know about the debugger/developer tools. You can even log stuff without ever writing/compiling directly from Chrome Developer Tools
OK. I would argue that if you spend that much time making your console look pretty (beyond useful), then you're either not spending enough time on things that matter (everything else, that the user may see) or you're grossly over budgeted.<p>Btw none of this is as useful as a breakpoint. Type `debugger;` in your code, refresh chromium or what have you with the dev panel open and inspect everything, jump over etc. ad nauseam. Pro tips use IntelliJ or webstorm for a really nice experience debugging.