3

Consider how JavaScript's Date constructor creates an object that returns a default string when referenced directly:

var date = new Date();
document.write(date); // Outputs string: Mon May 23 2016 08:48:14 GMT-0400 (EDT)
                      // Expected output: [object Object]

document.write('<br/>', date.getFullYear()); // Can call methods as expected.
document.write('<br/>', date.toString());

According to MDN documentation:

If no arguments are provided, the constructor creates a JavaScript Date object for the current date and time according to system settings.

(emphasis mine)

The Date constructor returns an object, yet when that object is referenced directly, it returns a string representing the current date and time instead of a representation of the methods and properties as expected.

How can I achieve the same behavior with an object constructor of my own creation?

For example:

// My CoolObj constructor function
var CoolObj = function () {
  var self = this;
  var i = 0;
  this.coolMethod = function () {
    i += 1;
    return self.coolProperty + ' and increment ' + i;
  };
  this.coolProperty = 'My cool string';
}

var myCoolObj = new CoolObj(); // Instantiate new object from constructor;
                               // Just like `var date = new Date();` above.

document.write(myCoolObj); // Outputs [object Object];
                           // I want to output a string, like Date does.
                           // For example: 'My cool direct-reference string.'

document.write('<br/>', myCoolObj.coolProperty); // Can call properties...
document.write('<br/>', myCoolObj.coolMethod()); // ...and methods as expected.

I'd like it to return a string of some kind when it is referenced directly, while providing the ability to call its methods and properties as normal.


UPDATE:

The linked question does provide the answer:
Is it possible to override JavaScript's toString() function to provide meaningful output for debugging?

tl;dr: Define CoolObj.prototype.toString which will get called by functions like console.log and document.write that attempt to cast objects to a string before output.

// My CoolObj constructor function
var CoolObj = function () {
  var self = this;
  var i = 0;
  this.coolMethod = function () {
    i += 1;
    return self.coolProperty + ' and increment ' + i;
  };
  this.coolProperty = 'My cool string';
}

// Define a custom `toString` method on the constructor prototype
CoolObj.prototype.toString = function () {
  return 'My cool direct-reference string.';
}

var myCoolObj = new CoolObj(); // Instantiate new object from constructor;
                               // Just like `var date = new Date();` above.

document.write(myCoolObj); // Outputs [object Object];
                           // I want to output a string, like Date does.
                           // For example: 'My cool direct-reference string.'

document.write('<br/>', myCoolObj.coolProperty); // Can call properties...
document.write('<br/>', myCoolObj.coolMethod()); // ...and methods as expected.
Community
  • 1
  • 1
gfullam
  • 11,531
  • 5
  • 50
  • 64
  • 3
    Possible duplicate of [Is it possible to override JavaScript's toString() function to provide meaningful output for debugging?](http://stackoverflow.com/questions/6307514/is-it-possible-to-override-javascripts-tostring-function-to-provide-meaningfu) – mdickin May 23 '16 at 13:07
  • @mdickin I am not seeking help for specifying format in console for objects. I am looking to discover how to add a default return statement for objects instantiated by constructor functions. – gfullam May 23 '16 at 13:47
  • 5
    @gfullam `new Date()` doesn't return a string, it returns an object. Calling `console.log()` on it calls the `Date.toString()` method. Running `typeof new Date()` returns "object" – mdickin May 23 '16 at 14:00
  • @mdickin I am aware that `new Date()` returns an object, which is why I referenced the MDN documentation stating such. It is precisely that fact that make me question Date's unique behavior in returning a string when directly referenced. I have revised my examples to divorce it from the usage of `console.log` to demonstrate what I observe in the Date-constructed objects that I would like to replicate with my own constructed objects. – gfullam May 23 '16 at 14:18
  • @bfmags That is an interesting question that only tangentially relates to mine, but its answers are hacky and introduce serious performance implications. I'm looking for an accepted "best practice" solution to my problem. – gfullam May 23 '16 at 14:21
  • @mdickin I wasn't making the connection. The linked question does provide the answer. Thank you. – gfullam May 23 '16 at 14:35
  • No problem, it can be confusing when the interpreter has special cases for certain objects. – mdickin May 23 '16 at 14:45

1 Answers1

2

I am not seeking help for specifying string format for objects in console.

But that's the behaviour you are seeing. There is no such thing as a "default return statement for objects".

Consider how JavaScript's Date constructor creates an object that returns a default string when referenced directly

It doesn't. It just creates an object. A special native Date object maybe, but there's nothing about "default strings".
It really is only the console (console.log) that formats these native Date instances special.

There is nothing you can do to achieve that yourself for arbitrary objects, what you are asking for is impossible.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I am not. I have revised my examples to divorce it from the usage of `console.log` to demonstrate what I observe in the Date-constructed objects that I would like to replicate with my own constructed objects. – gfullam May 23 '16 at 14:16
  • What you are trying to replicate is nonetheless a `console` effect only. There is no such behaviour of objects in JS. All you can do is write your own functions to treat your own object with special care. – Bergi May 23 '16 at 14:25
  • In the case of `document.write` (which you used in your new example), it does cast arguments to strings (like a few functions) - and then it's a duplicate of [the question that mdickin suggested in the comments](http://stackoverflow.com/q/6307514/1048572). – Bergi May 23 '16 at 14:27
  • I meant that functions like `console.log` or `document.write` treat objects passed to them with special care, not that the objects have special methods. – Bergi May 23 '16 at 14:30
  • I see what you're saying now. I didn't make the connection that `console.log` and `document.write` are casting the object to string. – gfullam May 23 '16 at 14:32
  • Essentially the answer is to modify `CoolObj.prototype.toString`. – gfullam May 23 '16 at 14:33
  • 1
    Yes, exactly. Though `console.log` only casts `Date` object to strings, and logs other special objects in other special ways (e.g. DOM nodes). – Bergi May 23 '16 at 14:36