2016-04-29 18 views
6

Sto scrivendo una gerarchia di oggetti in JavaScript, mi piacerebbe chiamare un metodo sul genitore di un oggetto quando ho ombreggiato quel metodo nell'oggetto.Modo più semplice/migliore per chiamare il metodo di prototipo in ombra?

Es .:

var Base = function Base(msg) { 
    this.msg = msg; 
} 
Base.prototype.log = function(){ 
    console.log("base log: " + this.msg); 
} 

var Sub = function Sub(msg) { 
    Base.call(this, msg); 
} 

Sub.prototype = Object.create(Base.prototype); 

Sub.prototype.log = function() { 
    console.log("sub log"); 

    this.__proto__.__proto__.log.call(this); // This works but __proto__ 
    Object.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this); // This works but is verbose 
    super.log(); // This doesn't work 
} 

var sub = new Sub('hi'); 
sub.log(); 

Vedi le tre linee nella parte inferiore della funzione Sub.prototype.log - c'è un modo migliore per fare quello che sto cercando di fare lì?

La seconda linea è la migliore che ho potuto trovare ma è molto prolissa!

+0

Sto votando per chiudere questa domanda come off-topic perché ritengo che questo appartenga a http://codereview.stackexchange.com – Dom

+4

Forse, ma non penso di chiedere una recensione, sono mi chiedo se esiste un meccanismo linguistico o un pattern di cui non sono a conoscenza quale sia la soluzione migliore per quello che sto cercando di fare. Felice di essere corretto se lo stackoverflow non è il posto giusto per questo. – sync

+1

Poiché la domanda è codificata come node.js, potresti anche utilizzare le classi es6. – hassansin

risposta

2

super non definito, ovviamente non funzionerebbe.

Si potrebbe desiderare di provare:

Sub.prototype.log = function() { 
    console.log("sub log"); 

    Base.prototype.log.call(this); 
} 

Un altro modo è quello di utilizzare il seguente metodo per ereditare classi:

function extend(Child, Parent) { 
    var F = function() { }; 
    F.prototype = Parent.prototype; 
    Child.prototype = new F();  

    // better to make it static (better practice in OOP world) 
    // e.g. Child.super = ..., 
    // but in your case: 
    Child.prototype.super = Parent.prototype;  
} 

Quindi, ecco un esempio:

// .. 
extend(Sub, Base); 

Sub.prototype.log = function() { 
    console.log("sub log"); 

    this.super.log.call(this); 
} 

In case di ES6:

class Base { 
    constructor(msg) { 
    this.msg = msg; 
    } 

    log(){ 
    console.log("base log: " + this.msg); 
    } 
} 

class Sub extends Base { 
    constructor(msg) { 
    super(msg); 
    } 

    log() { 
    console.log("sub log"); 
    super.log(); 
    } 
} 

var sub = new Sub('hi'); 
sub.log(); 
+0

Grazie, è pulito. Preferirei non avere il nome dell'oggetto "Base" hardcoded in quel caso - so che "super" non funzionerà nel mio caso d'uso ma è il tipo di cosa che mi piacerebbe fare, basta dire "chiama questo metodo su il prototipo del tuo genitore '. – sync

+0

@sync ha aggiornato la risposta –

1

Se si desidera mantenere il metodo originale senza utilizzare il nome Base, è possibile catturarlo utilizzando una chiusura prima di modificarlo.

(function() { 
    var superLog = Sub.prototype.log; 
    Sub.prototype.log = function() { 
     console.log("sub log"); 
     superLog(); 
    }; 
})(); 

In questo modo non v'è alcuna dipendenza da come si eredita dalla Base.

Nota a margine: la terminologia che stai cercando è "ignorare" il metodo di base.

+0

Grazie anche a te è una bella idea – sync

Problemi correlati