2013-08-02 5 views
5

Ich erstelle ein Spiel mit EaselJS, und ich frage mich, ob jemand erklären kann, wie das Vererbungsmuster in den Demo-Dateien funktioniert. Genauer gesagt, ich suche in der folgenden Datei: https://github.com/CreateJS/EaselJS/blob/master/examples/assets/Ship.jsEaselJS: Kann jemand das Vererbungsmuster in Demos erklären?

Zeile 7 Prototyp des Schiffs wird auf eine Instanz eines createjs.container() ...

var p = Ship.prototype = new createjs.Container(); 

Und dann auf der Leitung 28, ein Verweis auf der ursprüngliche Konstruktor wird gespeichert:

p.Container_initialize = p.initialize; //unique to avoid overiding base class 

Schließlich ist die Ship Objekt auf der Leitung initialisiert 30

p.initialize = function() { 
    this.Container_initialize(); 

Ich versuche, meinen Kopf um dieses Muster zu wickeln, weil es anders ist als alles, was mir in der Vergangenheit begegnet ist. Kann mir jemand erklären, warum Sie eine Instanz einer Klasse als Prototyp einer neuen Klasse verwenden möchten? Vielleicht zeigen Sie mich auf einen Link mit einer Erklärung für dieses Muster? Jede Hilfe hier wird sehr geschätzt ... Ich weiß, dass diese Frage ein wenig vage ist.

+0

Es ist ein gemeinsames Muster, überprüfen Tutorial hier https://developer.mozilla.org/ de-DE/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript – elclanrs

+0

Danke, das beantwortet meine Frage. Insbesondere: "Die spezialisierte Klasse wird häufig Kind genannt, und die andere Klasse wird häufig als Eltern bezeichnet. In JavaScript tun Sie dies, indem Sie der Kindklasse eine Instanz der Elternklasse zuweisen und sie dann spezialisieren. In modernen Browsern können Sie Verwenden Sie auch Object.create, um die Vererbung zu implementieren. " –

+0

Die beste Möglichkeit, all dies zu verstehen, ist, sich @ die Typescript-Definitionsdatei für EaselJS anzusehen. –

Antwort

8

Ich versuche, meinen Kopf um dieses Muster zu wickeln, weil es anders ist als alles, was ich in der Vergangenheit gesehen habe.

Ich auch nicht. Es macht nicht viel Magie, aber er Struktur ist definitiv ungewöhnlich. Siehe Correct javascript inheritance für das richtige Muster.

Kann mir jemand erklären, warum Sie eine Instanz einer Klasse als Prototyp einer neuen Klasse verwenden möchten?

Sie nicht. Sie möchten ein Objekt verwenden, das vom Prototypobjekt der übergeordneten Klasse erbt. Unfortunately many people use new ParConstructor for that - das funktioniert gut, wenn die Konstruktorfunktion leer ist. Wenn der Konstruktor Instanzeigenschaften erstellt oder andere Nebenwirkungen hat, kann dies zu Problemen führen. Die meisten Menschen scheinen das jedoch nicht zu bemerken oder sich darum zu kümmern.

Erklärung dieses Musters?

function Ship() { 
    this.initialize(); 
} 

Das gerade ruft die initialize Methode auf die neue Instanz (this in einem Konstruktor). Ich sehe keinen Vorteil gegenüber dem direkten Platzieren des Initialisierungscodes in dem Konstruktor, aber wie dem auch sei.

var p = Ship.prototype = new createjs.Container(); 

Wie oben erläutert, dies die Prototypkette der Einrichtung ist es, Methoden aus der Container „Klasse“ erben. Es führt wahrscheinlich eine unnötige Instanzinitialisierung durch, daher sollte es durch einen Object.create Aufruf ersetzt werden. Und es erstellt eine Abkürzungsvariable für den Prototyp.

// constructor: 
p.Container_initialize = p.initialize; //unique to avoid overiding base class 

Hier wird eine ausdrückliche Bezugnahme auf den Konstruktor der Eltern erstellt. Die initialize Eigenschaft auf p ist geerbt vom Container Prototyp, und jetzt ist es eine eigene Eigenschaft des p Objekts mit einem beschreibenden Namen gemacht. Das ist notwendig, weil ...

p.initialize = function() { 
    this.Container_initialize(); 
    … // property init stuff 

... hier eine eigene initialize Methode auf das Prototypobjekt deklariert wird, die geerbte eine Abschattung. Dennoch kann der "Super" -Initialisierungscode nun für die aktuelle Instanz unter Verwendung dieser dedizierten Eigenschaft aufgerufen werden. Doing das ist quitecommon, aber nicht auf diese Weise mit der Methode. Stattdessen wird call normalerweise verwendet, um den übergeordneten Konstruktor auf die untergeordnete Instanz anzuwenden.

besser (zumindest mehr vertraut):

function Ship() { 
    this.initialize(); 
} 

var super_p = createjs.Container.prototype, 
    p = Ship.prototype = Object.create(super_p); 

p.initialize = function() { 
    super_p.initialize.call(this); 
    … // property init stuff 

Oder alternativ ohne initialize:

function Ship() { 
    createjs.Container.call(this); 
    … // property init stuff 
} 
Ship.prototype = Object.create(createjs.Container.prototype); 
+0

Ich würde das abstimmen, aber ich brauche ein paar mehr Rufpunkte, bevor ich das tun kann. Danke für deine ausführliche Erklärung! –

Verwandte Themen