20

I have simple object that I want to display in console

var obj = { name: 'John', age: 22 }

If I type:

console.log(obj)

Object { name: "John", age: 22 }

If I type:

console.log('my object is: ' + obj)

my object is: [object Object]

console.log('my object is: %o', obj)

my object is: Object { name: "John", age: 22 }

How can I achieve this using a template literal?

If I type:

console.log(`my object is: ${obj}`)

my object is: [object Object]

1
  • 6
    Can also just do: console.log('my object is: ', obj);. Templates themselves are not smart about making a string representation of an object so you can't get the desired output purely from a template literal. They just invoke the default string conversion which is not what you want here. You will have to make the desired string representation yourself and pass that to the literal.
    – jfriend00
    Commented Jun 16, 2017 at 20:23

5 Answers 5

37

You could serialize the object with JSON.stringify.

var obj = { name: 'John', age: 22 };
console.log(`my object is: ${JSON.stringify(obj)}`);

2
  • ES6 note: Yes, but notice JSON.stringify returns undefined when working with classes and console.log works pretty similar to the good old toSource().
    – Txema
    Commented Jul 3, 2022 at 15:27
  • 1
    It also doesn't work well for non-POJO values like DOM nodes or even Dates, for which %o works much more reasonably.
    – dumbass
    Commented Apr 21 at 8:49
1

When you pass an element reference to a template literal and print it to the console, it resolves to [object Object] because JavaScript automatically converts the object (in this case, the DOM element) to a string using its toString() method. By default, the toString() method for an object returns a string in the format [object TypeName], which is not very informative.

However, when you pass the element reference directly to console.log(), the console prints it as <ELEMENT> (where ELEMENT is the actual HTML tag, like <div> or <span>) because the console is capable of recognizing and handling DOM elements. Instead of just calling toString(), the console prints a more user-friendly representation of the DOM element.

Breakdown

Here is a breakdown of the two approaches described above:

  • Template Literal
  • Console Logging Directly

Template Literal

When you use a template literal like `${element}`, JavaScript implicitly converts the element to a string using element.toString(), which results in [object Object].

const element = document.querySelector('.greeting');

// Greeting: [object HTMLParagraphElement]
console.log(`Greeting: ${element}`);
.greeting { color: green; }
<p class="greeting">Hello World</p>

Console Logging Directly

When you pass element directly to console.log(element), the console recognizes the DOM element and prints it in a more readable format, typically showing the tag name and attributes of the element.

const element = document.querySelector('.greeting');

// Greeting: <p class="greeting">Hello World</p>
console.log('Greeting:', element);
.greeting { color: green; }
<p class="greeting">Hello World</p>

Using outerHTML

If you want to print the element's HTML representation in a template literal, you could use the Element.prototype.outerHTML method instead:

const element = document.querySelector('.greeting');

// Greeting: <p class="greeting">Hello World</p>
console.log(`Greeting: ${element.outerHTML}`);
.greeting { color: green; }
<p class="greeting">Hello World</p>
\

Using JSON.stringify

If you want to print an object's JSON representation in a template literal, you could use the JSON.stringify method instead:

/* == Calls default toString() == */
const obj = { message: 'Hello World' };

// Greeting: [object Object]}
console.log(`Greeting: ${obj}}`);

// Greeting: {"message":"Hello World"}
console.log('Greeting:', obj);

// Greeting: {"message":"Hello World"}
console.log(`Greeting: ${JSON.stringify(obj)}`);


/* == Calls custom toString() == */
const obj2 = {
  message: 'Hello World',
  toString() {
    return JSON.stringify(this);
  },
};

// Greeting: {"message":"Hello World"}
console.log(`Greeting: ${obj2}`);
.greeting { color: green; }
<p class="greeting">Hello World</p>

0

To use template literal syntax to format console messages, you can use a custom tag function:

const cf = (pieces, ...values) => [
  String.raw(
    { raw: pieces.map(s => s.replace(/%/g, '%%')) },
    ...values.map(() => '%o')) + '%s',
  ...values, ''
];

const nums = [1, 2, 3, 4, 5];
const perc = 100 * nums.filter(x => x % 2).length / nums.length;

console.log(...cf`nums=${nums}, ${perc}% of odd numbers`);

(Why the extra %s at the end? This is a hack to ensure well-degenerating behaviour, which is to say, the format string always being interpreted as such, and e.g. console.log(...cf`%`) printing a single “%” and not “%%��. Stack Snippets does not actually work that way, but node.js and all major browsers do.)

If you dislike the spread syntax, you could instead write a wrapper taking a console logging function and returning a tag function:

const formatted = func => (pieces, ...values) =>
  func(String.raw(
    { raw: pieces.map(s => s.replace(/%/g, '%%')) },
    ...values.map(() => '%o')) + '%s',
    ...values, '');

const log = formatted(console.log);

const nums = [1, 2, 3, 4, 5];
const perc = 100 * nums.filter(x => x % 2).length / nums.length;

log`nums=${nums}, ${perc}% of odd numbers`;

// or use it directly, without an intermediate binding:

formatted(console.info)`nums=${nums}, ${perc}% of odd numbers`;

3
  • Please do not edit the question, it was like this for very long time and for a good reason. Regarding your answer it seems overly complex the accepted answer is the one I was looking for many years ago.
    – robert
    Commented Apr 21 at 20:32
  • @robert The question is not for you, it’s for others who have the same problem.
    – dumbass
    Commented Apr 21 at 21:49
  • sorry, but your edits are gpt generated. This question was good as it was for years. No need for any change.
    – robert
    Commented Apr 22 at 4:51
-1

var obj = { name: 'John', age: 22 }
log`This is obj: ${obj}`

function log(strings, ...values) {
   console.log(strings.reduce((p, c, i) => 
        `${p}${c}${values[i]?JSON.stringify(values[i]):''}`, ''));
}

3
  • 2
    such an over-complicated way to perform a simple operation. accepted answer serves the purpose.
    – Swaps
    Commented Oct 27, 2020 at 13:43
  • If supposedly being over-complicated were the only problem, I might have actually upvoted this one – but just like the accepted answer, it is a regression over using %o.
    – dumbass
    Commented Apr 21 at 8:47
  • (Although I would still personally consider String.raw({ raw: strings }, ...values.map(…)) a much cleaner way to write this.)
    – dumbass
    Commented Apr 21 at 14:41
-1

Easy way would be JSON.stringify.

And if you add null, 2 with the object you'll get formatted data.

JSON.stringify(obj, null, 2)

var obj = { name: 'John', age: 22 };
console.log(`my object is: ${JSON.stringify(obj)}`);
console.log('=================================================');
console.log(`my object is: ${JSON.stringify(obj, null, 2)}`);

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.