7

I saw this article on polymorphic callable objects and was trying to get it to work, however it seems that they are not really polymorphic, or at least they do not respect the prototype chain.

This code prints undefined, not "hello there".

Does this method not work with prototypes, or am I doing something wrong?

var callableType = function (constructor) {
  return function () {
    var callableInstance = function () {
      return callableInstance.callOverload.apply(callableInstance, arguments);
    };
    constructor.apply(callableInstance, arguments);
    return callableInstance;
  };
};

var X = callableType(function() {
    this.callOverload = function(){console.log('called!')};
});

X.prototype.hello = "hello there";

var x_i = new X();
console.log(x_i.hello);
1
  • 1
    I just impressed by your portrait and name. I suppose his name Shuren Zhou. Commented Jul 3, 2011 at 17:57

1 Answer 1

6

You'd need to change this:

var X = callableType(function() {
    this.callOverload = function(){console.log('called!')};
});

to this:

var X = new (callableType(function() {
    this.callOverload = function(){console.log('called!')};
}));

Notice the new as well as the parentheses around the callableType invocation.

The parentheses allows callableType to be invoked and return the function, which is used as the constructor for new.


EDIT:

var X = callableType(function() {
    this.callOverload = function() {
        console.log('called!')
    };
});

var someType = X();      // the returned constructor is referenced
var anotherType = X();   // the returned constructor is referenced

someType.prototype.hello = "hello there";  // modify the prototype of
anotherType.prototype.hello = "howdy";     //    both constructors

var some_i = new someType();           // create a new "someType" object
console.log(some_i.hello, some_i);

var another_i = new anotherType();     // create a new "anotherType" object
console.log(another_i.hello, another_i);

someType();      // or just invoke the callOverload
anotherType();

I really don't know how/where/why you'd use this pattern, but I suppose there's some good reason.

Sign up to request clarification or add additional context in comments.

3 Comments

Perhaps I'm doing something wrong, but this seems to break being able to call the instance—calling x_i() throws an exception along the lines of "object not function".
@luxun: By using new inline like that, you're invoking the function returned form callableType immediately as a constructor. I think what you're missing is that your code was adding to the prototype of X instead of to the constructor returned from X. The way I have it, X becomes the constructor itself, but you could reference it in another variable instead. I'll add an update.
Okay, I see. I actually thought it would make the instance callable, but I see this is not the case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.