Jitender
Jitender

Reputation: 7969

return standalone value from constructor not object

While learning the mongoDB I notice one constructor returning string with prototype function. For example

Following code will generate a random string, first 4 letter from string contain timestamp and to get the time stamp it has the prototype function.

const id = new ObjectID()  // 5c8766f4bcd712911ab81eea

console.log(id.getTimestamp()) // will print the date 

I was just working how it been done. I am trying to create the simple constructor in same way but it always return object. How can we make it to return single value instead of object with prototype function.

function getMyTime(){
 this.timestamp = new Date().getTime()
}

const timestamp = new getMyTime(); // should print timestamp 1552385374255
console.log(timestamp.printReadableDate()) // should print date Tue Mar 12 2019 15:39:34 GMT+0530 (India Standard Time)

Edited

class GetTime {

 constructor(){
 this.time = new Date().getTime();
 }

    getActualDate(){

  }

  toString(){
   return this.time 
  }
}

const stamp = new GetTime();

console.log(stamp) // should be 1552472230797

console.log(stamp.getActualDate()) //should be Wed Mar 13 2019 15:47:10 GMT+0530 (India Standard Time)

Upvotes: 1

Views: 168

Answers (3)

Louis
Louis

Reputation: 151401

The ObjectId class used by MongoDB is ultimately the ObjectId class provided by js-bson. This ObjectId class uses a facility provided by Node.js util.inspect to get itself printed as a string:

ObjectId.prototype[util.inspect.custom || 'inspect'] = ObjectId.prototype.toString;

What is going on there is that js-bson adds a method which has for name either util.inspect.custom or "inspect". The 2nd name is used for compatibility with Node versions prior to Node 6.6.0. In node, console.log uses util.format, which ultimately uses util.inspect to determine how to print each object passed to console.log, and it is possible to customize what util.inspect does by adding a method on the object that we want to customize. For Node versions prior to 6.6.0 the method must be named "inspect", for later versions it must have for name the value of util.inspect.custom.

So you can take a page out of what js-bson does and implement your class with:

const util = require("util");

class GetTime {
  constructor(){
    this.time = new Date().getTime();
  }

  toString() {
    return this.time;
  }
}

GetTime.prototype[util.inspect.custom || 'inspect'] = GetTime.prototype.toString

const stamp = new GetTime();

console.log(stamp);

Or this syntax might be more palatable to you or the development tools you use. I have used some code documentation tools in the past that are definitely more at ease with the following:

const util = require("util");

class GetTime {
  constructor(){
    this.time = new Date().getTime();
  }

  toString() {
    return this.time;
  }

  [util.inspect.custom || "inspect"]() {
    return this.toString();
  }
}

const stamp = new GetTime();

console.log(stamp); 

This syntax provides the same result as the earlier one, though there is an additional call.

As I mentioned above, this trick works only in Node. If I try passing an ObjectId object to console.log in Chrome, then Chrome does what it does with every other object: print the constructor name and the fields of the object. As far as I can tell, there's no cross-platform way to customize how console.log prints objects.

Upvotes: 3

Christophe Marois
Christophe Marois

Reputation: 6719

A constructor called with new always returns an object. Almost everything in javascript is an object, but some objects are treated differently, like Strings.

You can, however, "fool" the interpreter by extending one of the base object types:

class ObjectID extends String {
  constructor () {
    // Call String constructor with random hex
    super(Math.floor(Math.random() * 16777215).toString(16))

    this.timestamp = Date.now()
  }

  getTimestamp () {
    return this.timestamp
  }
}

const id = new ObjectId() // { [String: '2fff78'] timestamp: 1552718634749 }
console.log(`Id is ${id}`) // "Id is 2fff78"
console.log(id.getTimestamp()) // 1552718634749

Note: this is a very bad idea.

Upvotes: 0

str
str

Reputation: 44979

A constructor returns an object by definition.

The MongoDB JavaScript driver's ObjectID returns a "new ObjectID instance", not a string. But the ObjectID class also implements a toString method which returns a string representation of the ObjectID object instance.

Upvotes: 2

Related Questions