Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript "polymorphic callable objects"

Tags:

javascript

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);
like image 943
Aaron Yodaiken Avatar asked Jul 03 '11 17:07

Aaron Yodaiken


1 Answers

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.

like image 104
user113716 Avatar answered Oct 19 '22 05:10

user113716