8

I am trying to override the default toString method for my objects, Here is the code and the problem:

function test (){
     this.code = 0;//later on I will set these
     this.name = "";
}

test.prototype.toString= function(){
    return this.name + "\t"+ this.code +" \t "+this.anotherFunction();
}

console.log (Lion.toString()); //works correct i.e. calls my function
console.log (Lion); //doesn't call my function. Prints { code: 0, name: 'jack' }

doesn't toString get called by default?

kousha
  • 752
  • 2
  • 10
  • 23

4 Answers4

8

Came across this on google before finding an answer I liked, here is what I ended up doing:

You can use inspect and v8(chrome/nodejs) will use that from console.log() calls:

function Foo() {}

Foo.prototype.inspect = function() {
  return "[object Foo]";
}

console.log(new Foo());
Jacob Hacker
  • 1,501
  • 1
  • 13
  • 16
6

Not always. Browsers like Chrome allow you to inspect the object (for debugging purpose) via console.log().

Try this:

console.log (''+Lion);
palanik
  • 3,601
  • 1
  • 13
  • 10
5

I was interested in how to do this too, once I saw how nicely Immutable.js prints out objects:

var Immutable = require('immutable');
var map = Immutable.Map({ a: 1, b: 2 });
console.log(map); // Map { "a": 1, "b": 2 }

After some source code scanning, I discovered they pull it off by adding both toString and inspect methods to an object's prototype. Here's the basic idea, more or less:

function Map(obj) {
  this.obj = obj;
}
Map.prototype.toString = function () {
  return 'Map ' + JSON.stringify(this.obj);
}
Map.prototype.inspect = function () {
  return this.toString();
}

Having both toString and inspect methods means that the object will get logged out correctly in node (using inspect), and will be correctly formatted as a string if necessary (using toString).

EDIT: This only applies to node, browsers will still log out the object. If you don't want this, first convert it to a string either by calling toString or by concatenating it with another string: console.log('' + map).

Justin Tormey
  • 86
  • 1
  • 4
2

No. Adding something to prototype makes it available, but doesn't mean it will be called simply because you create an instance of the object to which it belongs.

For example:

function foo() {
   var bar = 123;
}
foo.prototype.show_bar = function() {
    console.log(this.bar);
}

var x = new foo(); // does not log anything
x.show_bar(); // logs 123

I think your confusion is thinking that console.log() automatically tries to convert its parameter to a string. It doesn't; it can output arrays, objects, functions, etc.

elixenide
  • 44,308
  • 16
  • 74
  • 100
  • I see, I was thinking when I console.log an object it always calls the toString method. but apparently it just print the object as it is. – kousha Feb 16 '14 at 00:33