Javascript - Template Strings Don't Pretty Print Objects

Your first example does not actually output a string to the console. Notice how properties is passed as a separate parameter argument (as it is surrounded by commas , and not string-concatenation operators +).

When you pass an object (or any JavaScript value) to console as a discrete argument it can display it how it wishes - including as an interactive formatted display, which it does in your first example.

In your second example, you're using templated-strings, but it's (generally) equivalent to this:

logString = "Description: " + description.toString() + ". Properties: " + properties.toString()";

And Object.prototype.toString() returns "[object Object]" by default. Note that this is a string value which is not particularly useful.

In order to get a JSON (literally JavaScript Object Notation) representation of an object used in a templated string use JSON.stringify:

logString = `Description: ${ description }. Properties: ${ JSON.stringify( properties ) }.`

Or consider extending toString for your own types:

myPropertiesConstructor.prototype.toString = function() {
    return JSON.stringify( this );
};

Can I use ES6 template strings to pretty print javascript objects?

Sure, but you have to convert the object to a pretty printed version before you pass it to the template literal (I'm sure there are libraries out there that do that. The poor man's version is JSON.stringify(obj, null, 2)).

However, since console.log accepts an arbitrary number of arguments, you should just pass the object as second argument so that it doesn't get converted to a string:

const logString = `Description: ${description}. Properties:`;
console.log(logString, properties);