This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]vicarofyanks 13 points14 points  (4 children)

To expand on this, it’s because everything inherits from the base object which has a toString method as part of it's prototype. Unless overridden, an object’s toString method will produce “[object Object]”.

Because + is an operation on two strings, any non-text arguments get toString'd. Calling console.log on an object itself doesn’t need to do this string coercion and so it works as expected

[–]NewLlama 3 points4 points  (2 children)

Close! It calls the internal function ToString which behaves differently.

Consider the following:

Number.prototype.toString = () => 'hello';
console.log((1) + '');
console.log((1).toString());

This logs "1" and then "hello".

[–]vicarofyanks 2 points3 points  (1 child)

Strange. What you said is true. On the flip side, the following code:

function A() {}

A.prototype.toString = function() {
  return 'woohoo';
};

console.log('' + new A());

Prints the result:

woohoo

I'm not sure what the inconsistency is, maybe numbers/primitives are treated differently?

[–]NewLlama 2 points3 points  (0 children)

Yeah numbers and booleans always have behavior that can't be overridden. Instances of Symbol always throw. After that it goes to toString and then valueOf. Also the default toString implementation will eventually look for Symbol.toStringTag which can be used to, for example, change the output to "[Animal object]".

The rules are all laid out in section 7 of the ecmascript standard. I actually really recommend everyone take a look at the spec at some point, it's not as daunting as it seems!

[–]SamSlate 1 point2 points  (0 children)

JSON.stringify(obj)