Thelostcause
Thelostcause

Reputation: 113

toString() method behaviour in Objects

So I was reading a book of Js and came across this beautiful topic of Object to primitive conversion. In the book the author says

For historical reasons, if toString or valueOf returns an object, there’s no error, but such value is ignored (like if the method didn’t exist). That’s because in ancient times there was no good “error” concept in JavaScript.

Now I tried this , but not getting as said in the book:

let user = {
    name: "John",
    money: 1000,

   toString(){
       return {
           name: 'Bong'
       };
   }
  };

  alert(user);

I got the error in the console saying :

Uncaught TypeError: Cannot convert object to primitive value

However, If I do this

alert(user.toString()); 

Then there is no erro, It gives [Object object]

Please explain this behaviour.

Upvotes: 3

Views: 975

Answers (3)

ibrahim mahrir
ibrahim mahrir

Reputation: 31692

In the first case, user.toString is called implicitly because alert is expecting a string and user is not a string. When user.toString() is called and the return value is not a string an error is thrown.

In the second case, user.toString is called explicitly by you, it doesn't matter if its name is toString or not because it returns the inner object just like any other method would (no primitve value is expected here). The inner object is then passed to alert, and its toString gets implicitly called which returns a string because it isn't overridden. The second case can be broken into two parts for clarity:

let obj = user.toString();    // first user.toString gets called, it will return the inner object
alert(obj);                   // obj.toString will implicitly gets called and since that will return a string everthing will be fine

If the inner object has a toString that returns an object, then the second case won't work either:

let user = {
  name: "John",
  money: 1000,

  toString() {
    return {
      name: 'Bong',
      toString() {                  // toString of the inner object is overridden
        return {};                  // ... and it returns an object
      }
    };
  }
};

alert(user.toString());            // now even the second case won't work because when toString of the inner object is called, a string is expected, but instead an object is returned which is a no no

Upvotes: 6

jagmitg
jagmitg

Reputation: 4546

[object Object] is the default string representation of an object.

When you're calling the object; toString() is called on the object, and the initial implementation returns [object Object].

If you want to review the object, you can either review it through console.log or through JSON.stringify(). You can also loop through all the properties and inspect them individually.

Example:

const objectOne = {};
const objectTwo = new Object;
const objectThree = {};

objectThree.toString = function () { return "Bong" };

alert(objectOne); // [object Object]
alert(objectTwo); // [object Object]
alert(objectThree); // Bong

Upvotes: 0

apena
apena

Reputation: 2321

alert does not auto convert non primitives to strings you need the toString() method for that. When you call toString() on a non primitive you get the default return which is its type and since everything in javascript is essentially an object the default return is [Object object].

Upvotes: -1

Related Questions