Is there any reason to manually `return` in a cons

2019-05-17 16:41发布

问题:

Typically, in a constructor function, the object that is bound to this within the function is returned by it when it is called with the new prefix. But I would imagine that it's also possible (I think I even read this in crockford's book) to manually return your own value. Are there any places where such a practice is useful?

回答1:

If you return a value type from the constructor, you'll get different behavior depending on if new was used. That's how String works. Look at this object in your JavaScript console:

{
    s: String("abc"),
    S: new String("abc")
}

Little s contains a string value, but big S contains a string Object. A subtle difference, perhaps.

You could go way beyond that and use the same function for different purposes:

function Foo() {
    return "abc";
}
Foo.prototype.DoSomething = function () {
    // something completely unrelated to "abc"
};
var a = Foo();      // The string "abc".  Does not have a DoSomething() method.
var b = new Foo();  // An Object with a DoSomething() method.  Doesn't know about "abc".

Depending on whether new was used, you'd get back something completely different.



回答2:

If you wanted to implement a singleton pattern this could be used, by making sure that after the first time the object is constructed you never construct another object - instead returning the first constructed object.

i.e.

if(!TheClass.singleton) TheClass.singleton = this;
return TheClass.singleton


回答3:

A constructor (i.e. a function called with new) always returns an object, which is this is the default. There are cases where you might protect against a call without new using say:

function Foo(arg) {
  if ( !(this instanceof Foo) ) {
    return new Foo(arg);
  }
  this.blah = arg;
}

So you return a different object to the function's this, but it still returns an instance of itself.



回答4:

Yeah, think of it like this.

item = function(id){
  if(alreadytaken(id)){
    return cache[id];
  }else{
    cache[id] = this;
  }
}

var newitem = new item(1);
var newitem2 = new item(1);

This example checks the ID to see if it already exists. If it does, then it will force a return of the object that already exists, something that I actually have used in the past.