DEV Community

Cover image for Cool Console stuff: Easy object inspection
Dylan Lacey
Dylan Lacey

Posted on • Edited on

Cool Console stuff: Easy object inspection

So here's a weird thing.

The console methods have their own C-like String Substitution methods.

Wait, String Substitution?

Literally, substituting part of a string for something else. In Programming land, that usually means building strings via interpolation or formatting strings:

guest = {name: "Fortesque-Delcourt", calling_gift: "a rather nice sherry"}
console.log( `Sir, Mr ${guest.name} has called. He's bought ${guest.calling_gift}` );

// Output:
"Sir, Mr Fortesque-Delcourt has called.  He's bought a rather nice sherry."
Enter fullscreen mode Exit fullscreen mode

OK so you can add strings, so what?

You can use Template Literals, or string concatenation, but the "C-Like" formatting referred to in the docs say you can also use templates with placeholders, passing the replacement strings as part of the method arguments:

console.log(
    "Sir, Mr %s has called. He's bought %s", 
    guest.name, 
    guest.calling_gift
);

// Output:
"Sir, Mr Fortesque-Delcourt has called.  He's bought a rather nice sherry."
Enter fullscreen mode Exit fullscreen mode

You're not restricted to substituting literal strings. Instead, the templating engine tries to convert the passed object into the data type specified by the placeholder.

Let's say we have an object representing the investment losses of a Victorian gentleman:

let losses = {
    pounds: 150,
    reputation: 45.7,
    body_parts: "Teeth"
        faith: ["The Markets", "New-Fangled Steam"]
}
Enter fullscreen mode Exit fullscreen mode

Here's what you get when you pass various types to the different placeholders:

Template String losses.body_part losses.pounds losses.reputation
"Lost: %s" "Lost: Teeth" "Lost: 150" "Lost: 45.7"
"Lost: %i" "Lost: NaN" "Lost: 150" "Lost: 45"
"Lost: %f" "Lost: NaN" "Lost: 150" "Lost: 45.7"

Is this useful?

No, not particularly. It does let you see at a glance if you pass a String in as an Integer or Float but... That's not gonna save the world.

What is useful is the Object placeholders, %o and %O.

The Object Placeholders

If you call console.log while combining an Object with a String (eg console.log("Your Object, Sir" + obj), you're likely to get back the stunningly unhelpful default toString output:

[object Object]
Enter fullscreen mode Exit fullscreen mode

This is Gross... But! If you use one of the Object placeholders, you'll get something that represents an enumeration of the properties and their values. What kind of something depends on the operator, and what kind of console you're using.

Node.js CLI

From the CLI, calling console.log with the uppercase %O operator will generate an inline enumeration.

Using the lowercase %o will generate a multi-line enumeration.

Inline (with %O)

console.log("%O", losses)

//Output:
{ pounds: 150, reputation: 45.7, body_parts: 'Teeth', Faith: ['The Markets', 'New-Fangled Steam'] }
Enter fullscreen mode Exit fullscreen mode

Multi-Line (with %o)

console.log("%o", losses)

//Output:
{
  pounds: 150,
  reputation: 45.7,
  body_parts: 'Teeth',
  Faith: ['The Markets', 'New Fangled Steam', [length]: 2]
}
Enter fullscreen mode Exit fullscreen mode

Browser Console

In the Chrome console, things act sort of backwards. Here, the lowercase "%o" operator will return an =inline= enumeration:

Inline (with %o)

console.log("%o", losses)

// Output:
> { pounds: 150, reputation: 45.7, body_parts: 'Teeth', Faith: ['The Markets', 'New-Fangled Steam'] }
Enter fullscreen mode Exit fullscreen mode

Object Linking (with %O)

The cool part, however, is with %O. Using the uppercase format, the output string will contain only the object's name... Which is clickable, taking you to the inspector to let you poke around!

Let's say our losses object is an instance of the Losses class, and it also contains some sort of history object. We can create a rich, readable debugging message which gives us easy access to object internals, but doesn't clutter up the console:

console.log(
    "Your %O exceed %d pounds. See %o.", 
    losses,
    losses.pounds,
    losses.history
)

//Output:
Your >Losses exceed 150 pounds. See >History.
Enter fullscreen mode Exit fullscreen mode

Wrap-up

So that's the power of Console String Substitution! Easy formatting for terse but richly informative console messages.

If you liked this, please hit the Dopamine (❤️) Switches (🦄) on the left, and subscribe to my writing for the next entry in the JS Console Debugging series!

Recognition

Header image is by @Sigmund, used under the Unsplash License.

Top comments (1)

Collapse
 
dylanlacey profile image
Dylan Lacey

Yup! As long as you're logging the object directly. Append it to a string and (at least when I checked) you tend to get the results of toString. I've added an explicative example; Thanks for the catch!

(FWIW Console.assert (which inspired me to write this post, as part of a longer post ) seems to prefer returning the toString representation on the command line and was sometimes returning it in the browser... But of course, now I can't replicate it and I look Foolish On The Internet)