2011-01-24 712 views
29

Supongamos que tengo una clase como esta:Javascript herencia y el método predominante

function Widget() { 
    this.id = new Date().getTime(); 
    // other fields 
} 
Widget.prototype = { 
    load: function(args) { 
     // do something 
    } 
} 

De esta clase creé algunas otras clases que heredan el mismo prototipo, pero tienen algunos métodos añadidos. Lo que quiero hacer es poder definir un método load() en las subclases que primero llama al método padre y luego ejecuta algún código. Algo como:

SpecialWidget.prototype = { 
    load: function(args) { 
     super.load(args); 
     // specific code here 
    } 
} 

Sé que no hay una palabra clave super en Javascript, pero debe haber una forma de hacerlo.

Respuesta

40

Puede simular así:

SpecialWidget.prototype = { 
    load: function(args) { 
     Widget.prototype.load.call(this, args); 
     // specific code here 
    } 
} 

O puede crear su propia propiedad súper así:

SpecialWidget.prototype.parent = Widget.prototype; 

SpecialWidget.prototype = { 
    load: function(args) { 
     this.parent.load.call(this,args); 
     // specific code here 
    } 
} 
+1

¡Supongo que esta es la solución más simple! Gracias –

+0

Esto me da un bucle infinito en mi código y no estoy seguro de por qué ... – CarbonDry

+0

Solo para agregar a mi comentario anterior, tengo un objeto que ya heredó de una clase y básicamente quiero especializar un método. – CarbonDry

1

No sé si esta es la mejor solución, pero podría hacer algo como esto:

function Widget() { 
    this.id = new Date().getTime(); 
} 
Widget.prototype.load = function(args) { 
    alert('parent load'); 
}; 

SpecialWidget = function(){}; 

    // Make the prototype of SpecialWidget an instance of Widget 
var proto = SpecialWidget.prototype = new Widget; 

    // Give the prototype a function that references the "load" from Widget 
proto.parent_load = proto.load; 

    // Give SpecialWidget its own "load" that first calls the parent_load 
proto.load = function(args) { 
    this.parent_load(args); 
    alert('special load'); 
}; 

var inst = new SpecialWidget; 

inst.load(); 

esto hace que el prototipo de SpecialWidget una instancia de Widget para que herede todo lo que Widget tiene.

Luego se hace una referencia a la load() de Widget llamada parent_load(), y crea su propia load() que llama a la parent_load() cuando se invoca.

+0

Puede usar 'Object.create (Thing.prototype)' en lugar de 'new Thing' si no atiende a clientes antiguos. – LeeGee

2

por lo primero, configura su 'subclase' al igual que

function SubClass(name) { 
    Super.call(this); 

    // stuff here 
} 

SubClass.prototype = new SuperClass(null); 
SubClass.prototype.constructor = SubClass; 

y entonces usted puede hacer

SuperClass.prototype.theMethod.apply(this); 

desde dentro de una aplicación subclase específica para invocar la aplicación del súper.

+0

Para aquellos, como yo, que cuestionaron la diferencia entre este enfoque y la llamada en la respuesta, la respuesta corta es que no hay ninguno. La respuesta larga es proporcionada por mozilla aquí ... https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply – Jackie

0

Sería posible almacenar el valor antiguo del método load en un cierre, si lo hizo su primordial de esta manera:

function Widget() { 
    this.id = new Date().getTime(); 
    // other fields 
} 

Widget.prototype = { 
    load: function(args) { 
     // do something 
     alert("Widget Prototype Load"); 
    } 
}; 

function SpecialWidget(){ 
}; 

SpecialWidget.prototype = new Widget(); 

(function(){ 
    var oldLoad = SpecialWidget.prototype.load; 
    SpecialWidget.prototype.load = function(){ 
     oldLoad(); 
     alert("new Load"); 
    }; 
}()); 


var x = new SpecialWidget(); 
x.load(); 

Funciona, pero no estoy seguro si es el mejor método .