SKU // 53

Object Display

Showing an object's contents is harder than showing a number or string. Put an object straight into text and you get something unhelpful. This lesson covers the right tool for each situation: debugging in the console, showing data on a page, and saving or sending it.

// The [object Object] Problem

const user = { name: "Ada", age: 36 };

console.log("User: " + user);
console.log(`User: ${user}`);
User: [object Object] User: [object Object]

When an object is turned into a string, JavaScript uses a generic default. You will see [object Object] on a page or in an alert any time you forget to pick specific properties.

// For Debugging: console.log

Pass the object as its own argument (with a comma, not +) and the console shows it properly, with expandable details:

console.log("User:", user);
User: {name: "Ada", age: 36}

For a list of similar objects, console.table draws a grid:

console.table([
  { name: "Ada",   age: 36 },
  { name: "Grace", age: 45 }
]);
(index) name age 0 "Ada" 36 1 "Grace" 45
Watch out
The console shows objects "live." If you log an object and change it later, expanding the logged copy may show the new values. To capture a snapshot, log JSON.stringify(obj) instead.

// For People: Pick the Properties

On a page, show specific properties in a sentence or layout:

const product = { name: "Desk Lamp", price: 24.5, inStock: true };

const text = `${product.name}: $${product.price.toFixed(2)} (${product.inStock ? "in stock" : "sold out"})`;
console.log(text);
Desk Lamp: $24.50 (in stock)

On a real page you would place that text into an element: document.getElementById("info").textContent = text;

// Looping to Show Every Property

const specs = { cpu: "M3", ram: "16GB", storage: "512GB" };

let lines = "";
for (const [key, value] of Object.entries(specs)) {
  lines += `${key}: ${value}\n`;
}
console.log(lines);
cpu: M3 ram: 16GB storage: 512GB

The [key, value] in that loop is a shortcut called destructuring. Each entry from Object.entries is a two-item array like ["cpu", "M3"], and const [key, value] unpacks it into two variables in one step. Without it, you would write entry[0] and entry[1]. A plain for...in loop works too:

const person = { name: "John", age: 30, city: "New York" };

let text = "";
for (let x in person) {
  text += person[x] + " ";
}
console.log(text);
John 30 New York
Watch out: person.x in a loop
Inside the loop you must write person[x]. person.x looks for a property literally named "x", which does not exist, so the loop would build "undefined undefined undefined". The key is in a variable, so it needs brackets.

Or just the values, joined with a separator:

console.log(Object.values(specs).join(" / "));   // "M3 / 16GB / 512GB"
M3 / 16GB / 512GB

// For Saving and Sending: JSON.stringify

JSON.stringify turns an object into a text format called JSON. It is how objects are saved to storage and sent to servers:

const user = { name: "Ada", age: 36, langs: ["JS", "Python"] };

console.log(JSON.stringify(user));
{"name":"Ada","age":36,"langs":["JS","Python"]}

Add two more arguments to make it readable. The 2 means "indent with two spaces":

console.log(JSON.stringify(user, null, 2));
{ "name": "Ada", "age": 36, "langs": [ "JS", "Python" ] }

JSON.parse goes the other way, turning JSON text back into an object:

const back = JSON.parse('{"name":"Ada","age":36}');
console.log(back.age);   // 36
36

// What JSON Leaves Out

const thing = {
  name: "Widget",
  secret: undefined,
  greet() { return "hi"; }
};

console.log(JSON.stringify(thing));
{"name":"Widget"}
Note
JSON holds data only. Methods and undefined values are silently dropped. Dates become strings. That is by design: JSON is for moving information, not behavior.

// A Custom toString Method

Give an object its own toString and it will use that whenever it is turned into text:

const point = {
  x: 3,
  y: 7,
  toString() { return `(${this.x}, ${this.y})`; }
};

console.log(`Point: ${point}`);
Point: (3, 7)

// Which Tool When?

Debuggingconsole.log("label", obj) / console.table
Showing to userspick properties into a template string
Saving / sendingJSON.stringify / JSON.parse
Object that prints itselfcustom toString()

// Quick Check

What does this log?

const item = { name: "Pen", price: 2 };
console.log("Item: " + item);
Show answer
Item: [object Object]. Joining an object into a string uses the generic default. Pick properties (item.name) or pass the object with a comma: console.log("Item:", item).

Which gives {"a":1}, ready to save or send?

  1. String({ a: 1 })
  2. JSON.stringify({ a: 1 })
  3. JSON.parse({ a: 1 })
  4. Object.values({ a: 1 })
Show answer
B. JSON.stringify turns an object into JSON text. A gives [object Object], C goes the other direction (text to object), and D gives the array [1].

What does this log?

const t = { n: 1, f() { return 2; }, u: undefined };
console.log(JSON.stringify(t));
Show answer
{"n":1}. JSON holds data only, so the method and the undefined value are silently left out.

// Try It

  1. Click Open Playground and run it. Then log user with a comma instead of + and compare the output
  2. Show three objects in a grid with console.table
  3. Stringify an object with indentation, then parse it back and read one property
  4. Add a toString() to an object and use it inside a template literal
// Video Walkthroughs
Last updated: Oct 10, 2026, 12:53 AM ET