[HN Gopher] Use console.log() like a pro (2020)
       ___________________________________________________________________
        
       Use console.log() like a pro (2020)
        
       Author : vuciv1
       Score  : 446 points
       Date   : 2021-04-12 14:26 UTC (8 hours ago)
        
 (HTM) web link (markodenic.com)
 (TXT) w3m dump (markodenic.com)
        
       | turdnagel wrote:
       | 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:
       | https://bugs.chromium.org/p/chromium/issues/detail?id=363796
        
         | ehsankia wrote:
         | Came to post this. been following that issue for 5 years now
         | and still no updates. Maybe if more people star it it'll
         | eventually get some attention :\
        
       | I_am_tiberius wrote:
       | 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.
        
         | sdfhbdf wrote:
         | Have you tried `jq`? https://stedolan.github.io/jq/
         | 
         | Maybe you can skip a step with pasting online.
        
         | rivn wrote:
         | do you know about util.inspect?
         | https://nodejs.org/api/util.html#util_util_inspect_object_sh...
        
           | I_am_tiberius wrote:
           | I did not. Thanks!
        
       | virgil_disgr4ce wrote:
       | I used to think `console.log` was only good for soothing and
       | assuaging the limbs of trees. Now I know better!
        
         | ajcp wrote:
         | This hurt to read. Don't get me wrong, I salute you for it, but
         | it still hurt...
        
           | virgil_disgr4ce wrote:
           | Hehe. <3
        
       | drhayes9 wrote:
       | If you select an item with the inspector (Chrome or Firefox), you
       | can now refer to that HTML element as $0 in the console.
        
       | mdaniel wrote:
       | 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:
       | https://developer.mozilla.org/en-US/docs/Web/API/Console
        
       | deckard1 wrote:
       | If I'm looking at values in node, I typically do
       | console.dir(obj, { depth: null })
       | 
       | However, if you need to inspect some object in a browser, don't
       | forget you can just insert:                  debugger
       | 
       | Which can be helpful at times.
        
       | laurent123456 wrote:
       | 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.
        
         | IggleSniggle wrote:
         | I love adding colors to my logs whether they are bash or
         | nodejs, but I generally check if the context is tty or not
         | before applying colors.
        
       | Kaze404 wrote:
       | My (newly discovered) favorite trick is using the comma operator.
       | Using it, you can (admittedly horribly) log anything in the
       | middle of any expression.
       | 
       | This for example will call `console.log(myVar)` and still call
       | `someFunction(myVar, someOtherArgument)`.                 myVar =
       | "12345"       someFunction((console.log(myVar), myVar),
       | someOtherArgument);
       | 
       | Pretty handy sometimes :)
        
       | alkonaut wrote:
       | 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?
        
       | brundolf wrote:
       | Another little trick; instead of doing:
       | console.log("some label: " + JSON.stringify(someObj))
       | 
       | pass it as a separate parameter:
       | console.log("some label: ", someObj)
       | 
       | and you'll get interactive expansions/manipulation in the console
        
         | simlevesque wrote:
         | No, this is totally different. In the second version, if
         | someObj changes after it was logged, when you'll expand it
         | you'll see the updated value. JSON.stringify freezes the value.
         | To get the same as the first example, but interactive, you have
         | to do:                 console.log("some label: " +
         | JSON.parse(JSON.stringify(someObj)))
        
           | brundolf wrote:
           | > you have to do
           | 
           | Technically you'd have to do
           | console.log("some label: ",
           | JSON.parse(JSON.stringify(someObj)))
           | 
           | > In the second version, if someObj changes after it was
           | logged, when you'll expand it you'll see the updated value
           | 
           | Yes, this is something to be aware of (and is getting beaten
           | to death throughout this comments section), but if like me
           | you mostly use plain objects in an immutable way, you
           | generally don't have to bother with cloning. Just keep this
           | in the back of your head and know when it won't do what you
           | want in a particular context.
        
             | simlevesque wrote:
             | > Just keep this in the back of your head
             | 
             | I would never debug with that mindstate. I don't trust
             | myself.
        
           | elwell wrote:
           | It's only different if you don't treat objects as immutable.
        
       | jackconsidine wrote:
       | 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.
        
         | _fullpint wrote:
         | Somethings don't log correctly if you use the built in
         | interpolation without using JSON.stringify. And if you use
         | stringify it'll actually "freeze" it and it will not be
         | interactive.
        
       | ajcp wrote:
       | 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.
       | 
       | 1: https://itsokayitsofficial.io/
        
         | freeopinion wrote:
         | Fun
         | 
         | But you should proofread it for typos.
        
           | ajcp wrote:
           | Thanks! My IDE is a terrible spell-checker
        
         | nkrisc wrote:
         | I just see a tree and a name, is that all it is? Not sure what
         | you meant but I'm on my phone so I can't really look at the
         | console.
        
           | ajcp wrote:
           | Go to the desktop version and open the dev tools console :)
        
         | duxup wrote:
         | I really like how that plays out as a sort of text only
         | alternative to a site, very cool ;)
        
           | ajcp wrote:
           | Hey thanks! I love the sense of discovery the dev console
           | provides. When you go to someone's site and hit `F12` to see
           | what's going on and BOOM, your confronted with a message,
           | like they were waiting for you personally. It's those little
           | bits of hidden magic the internet can provide.
        
         | fullwaza wrote:
         | Clever and clean, Nice work!
        
           | ajcp wrote:
           | Much appreciated!
        
       | aerovistae wrote:
       | 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.
        
         | simlevesque wrote:
         | Thank you for this
        
       | rattray wrote:
       | The ones that were new and interesting to me were towards the
       | end:                   console.table(obj)
       | console.time('x'); console.timeEnd('x')         console.trace()
        
       | intellix wrote:
       | 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
        
         | bluedino wrote:
         | >> 99% of Frontend developers don't know about the
         | debugger/developer tools.
         | 
         | How is that possible?
        
       | kebman wrote:
       | Hey, this is pretty neat! Never knew you could assert with it
       | also. This'll come in handy!
        
       | paweladamczuk wrote:
       | 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?
       | 
       | 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.
        
         | maddyboo wrote:
         | I don't understand your comment. Firefox and Chrome both have
         | actual debuggers as well, but many times console.log is a
         | faster way. What are the deficiencies you speak of?
        
           | paweladamczuk wrote:
           | I just think there are easier ways to debug your code than
           | including logging statements between your lines. And in some
           | environments I have never felt the need to do so.
           | 
           | I use the browser debuggers as well but I never saw a JS
           | stack trace approaching readability of a C# stack trace, and
           | there are also other things that make the entire debugging
           | experience more troublesome. Maybe that's just because I have
           | very little front-end experience (and no workflows and IDEs
           | properly set up to work with particular frameworks). Or maybe
           | it's because of the JS ecosystem. Threads like this one make
           | me lean towards the latter.
        
             | maddyboo wrote:
             | If there's an unhandled exception (or even a log message)
             | in your JavaScript, you can click on it in the console and
             | go straight to the source line, set a breakpoint and reload
             | or re-trigger the code, and now you've got a fully
             | interactive "stack trace" where you can inspect the values
             | of local variables at all levels of the stack. Or you can
             | set the debugger to automatically break on exceptions, or
             | even to break on events or DOM modifications.
             | 
             | I also can't stress enough how nice it is to have the
             | debugger integrated into the runtime environment as opposed
             | to an auxiliary debugger like GDB. No need to launch the
             | debugger after my code breaks because it's already there.
             | 
             | I think web technology has come a long way in the past few
             | years, but a lot of people still seem to hold a grudge
             | against it that I can only imagine they developed in the
             | days of "jQuery all the things". Are there still problems?
             | Massively yes, but what ecosystem is perfect? I think if
             | you don't have much recent experience, it can't hurt to try
             | these things again with an open mind and see if your
             | opinions still hold. I personally don't have any experience
             | with C# to be able to compare the debugging experience, but
             | compared to Go or C/C++ I think it is massively better.
             | 
             | I think with a good setup including a LSP server for your
             | editor, a good linter, and a type checker, frontend
             | development is actually one of the more enjoyable ways to
             | write code.
             | 
             | Tangential, but the only feature I really miss from browser
             | debuggers is time travel debugging. Mozilla was working on
             | implementing this in the Firefox DevTools as "WebReplay"
             | [0] but it was spun out as a separate project called
             | Replay.io [1] and I haven't heard much about it since then.
             | 
             | [0]: https://developer.mozilla.org/en-
             | US/docs/Mozilla/Projects/We...
             | 
             | [1]: https://www.replay.io/
        
         | sdfhbdf wrote:
         | You don't have to "rely" on it just like you don't have the
         | rely on `fmt.Println()` in golang for debugging.
         | 
         | A language/runtime/framework gives you options and you pick
         | your poison, browsers offer you step by step debuggers and REPL
         | out of the box and I actually think it's awesome in terms of
         | debugging, you can of course only use console.log(), and it's a
         | good place to start. When you're ready to move on there are
         | many more useful tabs in the browser devtools to debug with.
        
           | paweladamczuk wrote:
           | What worries me is that, apparently, there are many people
           | with a lot of web dev experience who haven't moved on. Why
           | haven't they moved on? I don't understand it.
           | 
           | I have yet to see a mid-level engineer using the same method
           | when debugging C# code.
           | 
           | Despite all that, I try to refrain from strong statements
           | about technologies. Just throwing around ideas.
        
       | Timothycquinn wrote:
       | 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.
       | 
       | 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();
       | 
       | 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.
        
       | [deleted]
        
       | yakshaving_jgt wrote:
       | There's pro, and then there's Steven Wittens. Open the console on
       | his site.
       | 
       | http://acko.net/
        
       | shp0ngle wrote:
       | Another tip I found very useful lately
       | 
       | You can use `$("selector")`, even without jQuery, in console.
       | (not sure if with firefox, works with safari and chrome)
       | 
       | And also `$x("path")` for xpath.
       | 
       | But note, this works only in console, it's not available from
       | javascript.
        
         | throwanem wrote:
         | Yep, it's an alias for document.querySelector. $$ aliases
         | document.querySelectorAll, too.
        
         | sfink wrote:
         | Looks like Firefox gives you `document.getElementById` with
         | `$`. You need $$("selector") for `document.querySelectorAll`.
         | Or rather, it looks like it does something like
         | `[...document.querySelectorAll(arg)]` (it returns an `Array`
         | not a `NodeList`.)
        
         | hiccuphippo wrote:
         | You can also use $0 to get the currently selected element in
         | the inspector.
        
       | boredpandas777 wrote:
       | 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.
        
       | baybal2 wrote:
       | console.table O_O
       | 
       | Wow, since when it was in JS?
        
         | kevinmgranger wrote:
         | Since Chrome 27 and/or Firefox 34:
         | 
         | https://developer.mozilla.org/en-US/docs/Web/API/Console/tab...
        
       | pjungwir wrote:
       | Wow there are some cool tricks here!
       | 
       | 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).
       | 
       | 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 _current_ 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:
       | h = {foo: "bar"}         console.log(h)         > Object { foo:
       | "bar" }         h.foo = "BAR"
       | 
       | Then you click the triangle and you see:                   V {..}
       | |   foo: "BAR"         | > <prototype>: Object { .. }
       | 
       | 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.
        
         | skratlo wrote:
         | That's an anti-feature. When you log something in traditional
         | sense you are recording something at that time.
        
           | SahAssar wrote:
           | It's more that the way that the console reflects how the
           | language works, and the console is not a log, it's a REPL (so
           | console.output would have been a nicer name than
           | console.log).
           | 
           | I think it would be more confusing if the console did not
           | work like the rest of the language does.
        
             | masklinn wrote:
             | > It's more that the way that the console reflects how the
             | language works, and the console is not a log, it's a REPL
             | (so console.output would have been a nicer name than
             | console.log).
             | 
             | That is entirely irrelevant. The primary purpose of
             | `console.log` is and has always be to generate output from
             | normal, non-interactive programs.
             | 
             | And it's completely wrong, `console.log` was absolutely
             | intended as a logging method, as evidenced by its siblings
             | `debug`, `info`, `warn` and `error`, pretty much like every
             | logging API out there.
             | 
             | It's also ahistorical revisionism "the console" was added
             | very late into the history of the language, it and the
             | entire console API were added by Firebug in the mid aughts.
             | The language had been a thing for a decade at that point.
             | 
             | > I think it would be more confusing if the console did not
             | work like the rest of the language does.
             | 
             | It would be the exact opposite. When I try to output
             | something, my intent is to show the state of that thing at
             | that point. That JS consoles are lazy (and even deferred)
             | has systematically been a pain point and a pain in the ass
             | leading to eager deep cloning to ensure I can see what I
             | actually have on hand at that point, especially in
             | mutation-heavy code.
             | 
             | I'm absolutely certain the number of times I've considered
             | the behaviour a feature rather than an annoyance is 0.
        
           | TeMPOraL wrote:
           | It's perhaps badly named, but it's also the only way it could
           | work in practice. A general facility for expanding any logged
           | object to arbitrary depths would be prohibitively expensive
           | to implement with static snapshots.
           | 
           | I've posted about it in more detail here:
           | https://news.ycombinator.com/item?id=26785429.
        
         | Farow wrote:
         | console.log can be an async function so it's not exactly a bug.
         | 
         | There's a more in-depth answer SO:
         | https://stackoverflow.com/a/23392650
        
       | jchw wrote:
       | Another trick that might be more practical for actually debugging
       | is using the object shorthand. For example, instead of...
       | console.log(x, y);
       | 
       | which contains the information you need, but lacks any useful
       | context, try...                   console.log({x, y});
       | 
       | ...which will print out like an object, including the key names.
        
         | brundolf wrote:
         | Posted this and then realized you beat me to it :)
        
         | tomduncalf wrote:
         | Yes, I love this one!
        
         | bobbylarrybobby wrote:
         | I really like this method but unfortunately most debuggers
         | print objects with keys in alphabetical order so there's no way
         | to get the keys you care about most at the top. Is there a way
         | to rectify this?
        
           | aardvarkr wrote:
           | This is going to make it significantly more janky but why not
           | just put it into a list inside the curly brackets? That
           | should preserve order while still triggering the object
           | debugging feature
        
         | thinkingkong wrote:
         | Or you can console.log(JSON.stringify(x, null, 2));
        
           | brundolf wrote:
           | I think you misunderstood the intent of the GP
        
             | matja wrote:
             | But this way is easier to reconcile the output, because the
             | values logged shown are what they where at the time of the
             | console.log(), not at the time of expansion (later).
             | 
             | Try this in a browser console:
             | x={a:1,b:{c:1}};console.log(x);x.b.c=2;
             | 
             | then 'expand' the object, 'c' will be logged as 2, not 1
        
               | brundolf wrote:
               | The original commenter was creating the object at log-
               | time, though, which means it wouldn't be shared by
               | anything else. Unless x or y is an object, but in that
               | case the issue is completely tangential to the original
               | suggestion
               | 
               | And anyway- JSON.parse(JSON.stringify(x)) would be
               | preferable because you'd still get the browser's rich
               | object exploration
        
               | da39a3ee wrote:
               | > Unless x or y is an object, but in that case the issue
               | is completely tangential to the original suggestion
               | 
               | Of course we have to assume that x and y may be objects!
        
         | ljm wrote:
         | The best trick for actual debugging is to leverage your browser
         | console.
         | 
         | In a local build you basically have a 1:1 mapping of source
         | code to deployed code and the debugger here basically becomes
         | your IDE. You can hit Ctrl+Shift+P in the inspector and use the
         | same kind of fuzzy file matcher you have in Sublime Text or VS
         | Code, and from there you can set breakpoints, modify the code
         | in memory, and so on. The console will reflect on the entire
         | scope and annotate the code with their runtime values, the same
         | as you get when working inside a JetBrains IDE.
         | 
         | But it's JS, so you can tweak it without committing it to disk
         | and so you get some form of REPL driven development. I can't
         | remember the last time I've used a console.log over setting a
         | breakpoint in the debugger and fucking with the application
         | state at that point to understand an issue.
         | 
         | You can get quite close to that after you've bundled your code
         | and deployed it to a server, so long as you've got good source
         | maps going on.
         | 
         | Print debugging is invaluable, but I can't help but think
         | there's something of Smalltalk or Lisp in how you can mess with
         | your app within a sandbox through the inspector, at runtime.
         | The only thing that breaks the model is the transpilation and
         | minification, without sourcemaps.
        
           | meetups323 wrote:
           | FYI VS Code's JS debugger speaks Chrome Debugger Protocol and
           | allows you to use the built in Debug Console just as you
           | would the browser's debug console, also it's possible to set
           | browser breakpoints/etc., and you get inline value hovers.
        
         | tshaddox wrote:
         | Unfortunately that tends to print the object with collapsed
         | values, requiring you to expand the object to actually see any
         | of the values.
        
           | brundolf wrote:
           | If they're primitives most consoles will show you the values
           | without expansion
        
           | dekerta wrote:
           | You could do console.table({x, y}) if you really want to see
           | them initially expanded
        
           | ollien wrote:
           | I much prefer it being collapsed. When dealing with large
           | objects, the firehose can be annoying.
        
             | pjerem wrote:
             | Then, one day, after 12 hours chasing a race condition bug,
             | you learn that when you expand objects from console.log, it
             | shows you the current value of properties and not the
             | values at the time of the console log. Because the values
             | are evaluated when you click on the arrow.
             | 
             | Then you quit web development and start a new career.
        
               | randomsearch wrote:
               | You are not wrong. Is this a repl or a debugger? Because
               | it seems to be mixture? How is that helpful?!
        
               | matja wrote:
               | I was just about to mention this, I wasted a solid hour
               | or two on this until I realised what was happening.
        
               | brundolf wrote:
               | As I pointed out in another comment:
               | console.log({x, y});
               | 
               | the wrapping object is being created at log time, so its
               | values will never be changed after the fact. That could
               | still happen with the contents of x or y themselves, but
               | then it's no different from the original way
               | (console.log(x, y);)
        
               | evan_ wrote:
               | We can actually just test this. Here's some code:
               | const x = {value: 0};         console.log(x);
               | console.log({x});         x.value = 1;
               | 
               | Running that in the latest Chrome javascript console, we
               | see that the first version prints `{value: 0}` and the
               | second prints `{x: {...}}`. When you expand the second
               | one, it will show `{x: {value: 1}}`.
        
               | Lex-2008 wrote:
               | yep, but then when I expand (click triangle) the {value:
               | 0} line, it shows "value: 1" on the next line, only to
               | rise the confusion.
               | 
               | To be fair, there is also an "i" in a square, reminding
               | me about this behaviour.
        
               | brundolf wrote:
               | > its values will never be changed after the fact
               | 
               | By this I mean, the x and y in the output will never
               | themselves change value. They may be _mutated_ , but they
               | cannot be _reassigned_ in the printed object. The printed
               | object is exclusively referenced by the console itself,
               | even if the nested objects within it may be referenced
               | elsewhere.
               | 
               | > That could still happen with the contents of x or y
               | themselves, but then it's no different from the original
               | way (console.log(x, y);)
               | 
               | By this I mean exactly what you demonstrated, the point
               | being that it had nothing to do with the original
               | suggestion made by jchw.
        
               | Folcon wrote:
               | The really fun part is doing this :)...
               | 
               | Evaluate the expression:                   const x =
               | {value: 0};         console.log(x);
               | console.log({x});         x.value = 1;
               | 
               | You get this:                   {value: 0}         {x:
               | {...}}
               | 
               | Expand the first arrow of the `x:`:                   v
               | {x: {...}}          > x: {value: 1}
               | 
               | Now evaluate:                   x.value = 3
               | 
               | Then expand the second arrow:                   v {x:
               | {...}}          > x:              value: 3
               | 
               | Now if you unexpand the arrow, you get 1, but if you
               | expand it you get 3 =)... (Well at least in chrome)
        
               | Lex-2008 wrote:
               | > Now if you unexpand the arrow, you get 1, but if you
               | expand it you get 3 =)...
               | 
               | Moreover, if you expand arrow next to {value: 0}, you
               | will see literally this:                   v {value: 0}
               | [i]             value: 3
        
               | TeMPOraL wrote:
               | FWIW, it's not like it could work in any other way.
               | 
               | When you console.log() an object, it just stores a
               | _pointer_ to the object, and decorates it with an
               | interactive label containing some text, so that it looks
               | nice. This is fast to do, and most of the time, it 's
               | exactly what you want.
               | 
               | To log a static snapshot with equivalent interactive
               | expansion capability, console.log() would have to do a
               | _general deep copy_ of your object - it would have to
               | walk every pointer in the object and replace the pointee
               | with its own recursive full deep copy, making sure to
               | detect and handle cycles well, and keeping track of every
               | replacement to ensure referential integrity (e.g. if two
               | random objects A and B both have a pointer to the same
               | object C, the copied A ' and B' better both point at the
               | same C'). An unlucky console.log() could easily copy half
               | of your heap into the console, and god help you if you
               | logged a DOM element.
               | 
               | (Also, all these copies would not be garbage-collected
               | until you cleared the console.)
               | 
               | An universal deep copy is impractical to implement
               | (notice how nobody seems to ever implement it, _at all_ ,
               | in any programming language), and having console.log() do
               | one would be an incredibly powerful and unpredictable
               | footgun. Meanwhile, if you want to log a static snapshot
               | of an object, all you need to do is to write
               | console.log(cloneForLog(object)), where cloneForLog() is
               | a function you wrote that does whatever copying is
               | appropriate in your situation.
               | 
               | I think the only bad thing about console.log() is that
               | this behavior is not taught to people as a core and
               | important aspect of the function. I guess maybe if
               | console.log() was restricted to strings, and something
               | like console.logPresentation() was a _separate_ function
               | for printing objects, people would check the docs first
               | and wouldn 't be surprised.
        
               | newsbinator wrote:
               | Rite of passage for every web developer. The moment when
               | you realize this is the moment when the universe makes
               | sense again... after long hours of total confusion.
        
               | drinchev wrote:
               | Yeah I don't remember how I found about this, but I
               | remember it involved some
               | `console.log(JSON.stringify(...))`. It's tricky to
               | notice.
        
               | inbx0 wrote:
               | And then you can't repro the bug anymore because it was
               | related to Mobx observables or whatever and that
               | JSON.stringify suddenly made it work so you just... leave
               | it there...
        
               | drinchev wrote:
               | Fun story explaining this to the PR reviewers though :D
        
           | JonathonW wrote:
           | On Node, console.dir(x, {depth: null}) will print the object
           | fully expanded (even in cases where console.log by itself
           | won't). Pass something other than `null` to `depth` and it'll
           | recurse to that depth, as well.
           | 
           | Doesn't help on browser, though; the options arg to
           | console.dir isn't part of the standard there.
        
             | josephg wrote:
             | You can console.log(JSON.stringify(x, null, 2)) to pretty-
             | print the object as JSON. It doesn't look as good, but
             | it'll expand and show you the value as it was the moment
             | you logged it. (As opposed to the value when you open it in
             | dev tools)
        
         | dylan604 wrote:
         | thank you. hadn't seen that before
        
       | onion2k wrote:
       | 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.
       | 
       | 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.
       | 
       | (This probably only works in Chrome)
        
         | sfink wrote:
         | In Firefox, you click on the gear icon in the top right of the
         | console, then check "Show Timestamps".
         | 
         | Though you probably want the per-tab Console there (ctrl-
         | shift-k). ctrl-shift-j would give you the multiprocess browser
         | console, which is very noisy.
        
       | [deleted]
        
       | keyle wrote:
       | 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.
       | 
       | 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.
        
       | SavantIdiot wrote:
       | Not gonna lie, read this hoping to pat myself on the back for
       | being a pro, twist: learned some cool stuff, console.memory()?
       | Neato!
        
         | drhayes9 wrote:
         | Doesn't work in Firefox, unfortunately. :sadface:
        
           | jordan314 wrote:
           | Yeah, also it's console.memory not console.memory()
        
         | umaar wrote:
         | Another! If you inspect a console.logged function, DevTools
         | shows you the scope it has access to.
         | 
         | https://umaar.com/dev-tips/117-inspect-function-scope/
        
         | SamBam wrote:
         | Me too. `console.table` is totally new to me as well.
        
       | yepthatsreality wrote:
       | > Using console.log() for JavaScript debugging is the most common
       | practice among developers. But, there is more...
       | 
       | 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.
       | 
       | You should use a debugger in every language you can for
       | development.
       | 
       | Neat tricks though.
        
         | ehsankia wrote:
         | If you want to quickly log stuff without adding a log
         | statement, you can right click the line gutter in sources and
         | add a logpoint. Similar to a breakpoint, but logs every time it
         | hits that line. Not modifying the source code so you don't have
         | to remember about removing it.
        
       | tfsh wrote:
       | 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
        
       | uyt wrote:
       | 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:                 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;`);
       | 
       | If you paste this you should see the HN logo display in your
       | console. Credit for the image trick goes to
       | https://github.com/adriancooney/console.image
       | 
       | I actually use this in the real world a lot for working with
       | animated canvases. Appending the current frame into the page is
       | not the same since you lose the context from being interleaved
       | with your other log messages.
        
       | supermatt wrote:
       | This brings to light an issue I have encountered recently which
       | has caused me to rely on console.log more than I would like.
       | 
       | 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.
       | 
       | Has anyone experienced this? If so, is there a way to fix it, or
       | is this what I can expect when using async/await?
        
         | Kyro38 wrote:
         | I've experienced this when the async/await is not handled
         | natively (for example when targeting ES5/6) and chrome or the
         | sourcemap have it difficult to map the original code to the
         | executed js.
        
       | kache_ wrote:
       | I keep on coming back to debugging with print statements. I
       | (embarrassingly) started using console.trace more often only
       | recently.
        
       | nicetryguy wrote:
       | Nice little article. Learned a new trick or two.
       | 
       | I'd love to see one on the step-thru debugger!
        
       | swyx wrote:
       | for what its worth i have this guy blocked on twitter - all he
       | does is repost basic APIs you can get from MDN. classic grift
       | playbook.
        
         | sdfhbdf wrote:
         | Not everybody have already learned everything. Sure,
         | documentation is a really good source of truth, but for some
         | people simpler introduction than a whole whitepaper's worth of
         | information, which you get in MDN, might be more digestible.
         | 
         | I don't think closing on people just starting to learn is a
         | good way to expand the field of software engineering.
        
       | Pfhreak wrote:
       | Rather than using                 %s, %i, %o, %f, etc.
       | 
       | You can use a templated string, like this:                 `This
       | is a string that has been printed ${someVar} times.`
        
         | vitus wrote:
         | That works great for strings / numbers, not so much for objects
         | (unless you really want to see "[object Object]" in your debug
         | strings).
        
       | lights0123 wrote:
       | %s - string         %i or %d - integer         %o or %O - object
       | %f - float
       | 
       | Why were these ever specific types, instead of just one option
       | that looks at the parameter type?
        
         | sombremesa wrote:
         | > parameter type
         | 
         |  _laughs in JS_
        
         | yunohn wrote:
         | Probably as a remnant of C's printf? Python has the same for
         | its string formatting.
        
         | okbake wrote:
         | I could see both, but things like integer vs float couldn't be
         | determined from the type, since you just have the single
         | `number` type. That being said, you could just convert to an
         | int on the value you're passing in rather than having the
         | interpolation do it for you. Same thing with object vs string,
         | you could pass in `obj.toString()` instead of just `obj` with
         | an `%s`
        
       | faichai wrote:
       | Was reading this thinking the biggest pain is being unable to
       | wrap console.log and keep line numbers.
       | 
       | But some Googling [1] shows that this has now been fixed by being
       | able to blackbox your wrapper scripts.
       | 
       | [1] https://gist.github.com/paulirish/c307a5a585ddbcc17242
        
       | umaar wrote:
       | I've put over 200 tips like that on my website:
       | https://umaar.com/dev-tips/
       | 
       | 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).
       | 
       | 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.
        
         | Felk wrote:
         | Speaking of memory leaks, I once had to debug a memory leak
         | caused by console log entries. Objects that are logged to the
         | console are prevented from being garbage collected, even if the
         | console was never opened. That includes DOM nodes or I think
         | also handles to WebGL textures.
        
           | umaar wrote:
           | Interesting, I think that's because logged objects are
           | "live", so you can inspect their current state, not just the
           | state at the point of logging.
        
           | franklyt wrote:
           | That's interesting. I'm guessing console.log appends to the
           | window object somewhere, which is a fairly common method of
           | image preloading.
        
         | ajcp wrote:
         | Amazing! Thanks so much for this.
        
         | [deleted]
        
       | christiansakai wrote:
       | I often always do this to deep print my javascript object.
       | console.log(JSON.stringify(myObject, null, 4));
        
         | tantalor wrote:
         | This is great trick because the console will keep a reference
         | to your object, not a copy, so if it changes between the time
         | it was logged and now then the log expando shows the new value,
         | not the old value.
         | 
         | By printing out the object you get a point-in-time snapshot
         | rather than a reference to a mutable object.
        
           | christiansakai wrote:
           | Yup, learned it the hard way lol.
        
       | eyelidlessness wrote:
       | 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.
        
       | [deleted]
        
       | ehsankia wrote:
       | 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.
       | 
       | 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.
        
       | [deleted]
        
       ___________________________________________________________________
       (page generated 2021-04-12 23:00 UTC)