2011-01-24 9 views
29

Si supponga Ho una classe come questa:Javascript eredità e il metodo prioritario

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

da questa classe ho creato alcune altre classi che ereditano lo stesso prototipo, ma hanno alcuni metodi aggiunto. Quello che voglio fare è essere in grado di definire un metodo load() nelle sottoclassi che prima chiama il metodo genitore e poi esegue del codice. Qualcosa del tipo:

So che non ci sono parole chiave super in Javascript, ma ci deve essere un modo per farlo.

risposta

40

È possibile simulare in questo modo:

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

Oppure si può creare la vostra proprietà super come questo:

SpecialWidget.prototype.parent = Widget.prototype; 

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

Immagino che questa sia la soluzione più semplice! Grazie –

+0

Questo mi dà un ciclo infinito nel mio codice e non sono sicuro del perché .. – CarbonDry

+0

Solo per aggiungere al mio commento precedente, ho un oggetto che è già stato ereditato da una classe e voglio fondamentalmente un metodo specializzato. – CarbonDry

1

Non so se questa è la soluzione migliore, ma si potrebbe fare qualcosa di simile:

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(); 

questo rende il prototipo di SpecialWidget un'istanza di Widget in modo che erediti tutto ciò che ha Widget.

poi fa un riferimento al load() di Widget chiamato parent_load(), e crea la propria load() che chiama il parent_load() quando viene richiamato.

+0

Puoi usare 'Object.create (Thing.prototype)' piuttosto che 'nuova cosa' che non soddisfi i vecchi client. – LeeGee

2

così prima, si imposta la 'sottoclasse' in questo modo

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

    // stuff here 
} 

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

e allora si può fare

SuperClass.prototype.theMethod.apply(this); 

dall'interno di un'implementazione sottoclasse di richiamare espressamente l'implementazione del super-.

+0

Per quelli, come me, che hanno messo in discussione la differenza tra questo approccio e la chiamata nella risposta, la risposta breve è che non ce n'è. La lunga risposta è fornita da mozilla qui ... https: //developer.mozilla.org/it-it/docs/Web/JavaScript/Riferimento/Global_Objects/Function/apply – Jackie

0

Sarebbe possibile memorizzare il vecchio valore del metodo load in una chiusura, se avete fatto la vostra prioritario in questo modo:

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(); 

Funziona, ma non sono sicuro se è il metodo migliore .