DEV Community

Cover image for [ object Object ]
Abolfazl Soltani
Abolfazl Soltani

Posted on

[ object Object ]

Image description

We see two fields in this object that are part of the prototype of JavaScript objects.
One of them is toString(), and the other is valueOf().

If you’re a frontend developer, or have even written JavaScript once, you’ve probably seen [object Object] appear in your output or console logs.

What is this mysterious string? Why do we see it instead of a useful string representation of our object? 🤔

What exactly is [object Object]?

Despite appearances, [object Object] is not an array or some special string. It’s the default string representation of a plain JavaScript object.

Here’s why:
JavaScript’s type system works on values, not variables. When you try to convert an object to a string or number (called type coercion), JavaScript internally uses the ToPrimitive algorithm to figure out how to do this.

ToPrimitive tries to convert objects by calling two special methods on them:

  • 1. toString()
  • 2. valueOf()

These methods help JavaScript decide how to represent the object as a primitive value (string or number).

for example:

console.log(obj < 50);
Enter fullscreen mode Exit fullscreen mode

JavaScript assumes you want to convert obj to a number here.

or

console.log(obj + '');
Enter fullscreen mode Exit fullscreen mode

JavaScript assumes you want to convert obj to a string in this string concatenation.

Where to learn more about ToPrimitive?

You can read the official specification here:
ToPrimitive Algorithm — ECMAScript® 2024 Language Specification

Why did I write this article?

Because you can customize these conversion methods (toString() and valueOf()) yourself! 🤩

Whether you use plain JavaScript or libraries, understanding and controlling this conversion is powerful. You can:

  • Customize how your objects appear in logs or UI.

  • Provide clearer debugging info — show exactly which object caused an error or was coerced implicitly.

  • Manage unexpected JavaScript coercion behavior on your terms.

Example:

const obj = {
  valueOf() { return 42; },
  toString() { return "hello"; }
};

console.log(obj + 1);  // Output: 43
Enter fullscreen mode Exit fullscreen mode

Here, because obj.valueOf() returns a primitive number, JavaScript uses that during addition.

  • Also, consider that if JavaScript calls either toString() or valueOf() during type conversion, but the returned value is still an object (not a primitive), then ToPrimitive will try the other method (valueOf() if it originally called toString(), or vice versa). If both methods return objects instead of primitives, JavaScript throws a TypeError.

Summary

  • [object Object] is the default string from an object's toString() method.

  • JavaScript uses toString() and valueOf() during type coercion with the ToPrimitive algorithm.

  • You can override these methods for better control and debugging.

Top comments (5)

Collapse
 
klawdyo profile image
Claudio Medeiros

console.log(obj < 50) is bool, not number.

Collapse
 
hookjs profile image
Abolfazl Soltani • Edited

Thanks for sharing!
JavaScript first coerces obj to a primitive value before comparing operands. Since one of the operands is a number, the ToPrimitive algorithm tries to convert obj to a number using valueOf().
Then it compares the two numbers and returns a boolean. So,
console.log(obj < 50)
results in a boolean, not a number.

Collapse
 
gamelord2011 profile image
Reid Burton

bool === number (kinda)
in binary, a boolean, and one bit (0, or 1) are the same, 0 === false, 1 === true

Collapse
 
nevodavid profile image
Nevo David

man i still get tripped up whenever [object Object] pops up in logs, lol. ever run into a time where tweaking toString or valueOf actually saved you time later?

Collapse
 
hookjs profile image
Abolfazl Soltani

For me, probably not — but for some juniors or interns on the project, it could be helpful.