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 );
};
As a further improvement in modern browsers, you can render an interactive JSON object in your console output then you can use the %o string substitution specifier in your format-string, like so:
var foo = { a: 123, b: 'bar' };
console.log( 'Logged object follows this: %o - and some following text too', foo );
...which appears like this in Chrome's console:

...it's interactive, see:
