2011-07-03 26 views
7

Vi this article on polymorphic callable objects y estaba tratando de hacer que funcione, sin embargo, parece que no son realmente polimórficos, o al menos no respetan la cadena de prototipos.javascript "objetos invocables polimórficos"

Este código imprime undefined, no "hello there".

¿Este método no funciona con prototipos, o estoy haciendo algo mal?

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

Me impresionó su retrato y su nombre. Supongo que su nombre es Shuren Zhou. – xis

Respuesta

6

Usted había necesidad de cambiar esta situación:

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

a esto:

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

Aviso del new, así como los paréntesis alrededor del callableType invocación.

El paréntesis permite invocar callableType y devolver la función, que se utiliza como el constructor para 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(); 

Realmente no sé cómo/dónde/qué debería usar este patrón, pero supongo que hay una buena razón.

+0

Tal vez estoy haciendo algo mal, pero esto parece romperse al poder llamar a la instancia-llamada 'x_i()' arroja una excepción en la línea de "objeto no función". –

+0

@luxun: Al usar 'new' inline así, estás invocando la función devuelta de' callableType' inmediatamente como un constructor. Creo que lo que te estás perdiendo es que tu código se estaba agregando al prototipo de 'X' en lugar de al constructor devuelto por' X'. De la forma en que lo tengo, 'X' se convierte en el propio constructor, pero en su lugar podrías hacer referencia a él en otra variable. Añadiré una actualización. – user113716

+0

Está bien, ya veo. De hecho, pensé que haría * la instancia * invocable, pero veo que este no es el caso. –

Cuestiones relacionadas