Frage

Ich weiß, dass es viele ähnliche Fragen ist es Tonnen von großen Antworten. Ich habe versucht, bei den klassischen Vererbungs Methoden zu suchen, oder solche Verschlussmethoden usw. Irgendwie halte ich sich mehr oder weniger „Hack“ Methoden zu mir, da es nicht wirklich tut, was das Javascript zu tun ist so konzipiert. (Welcome jemand korrigiert mich wenn ich falsch liege). OK, solange es funktioniert, zufrieden ich mit dem klassischen Vererbungsmuster wie:

PARENTClass = function (basevar) { do something here; };
PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen 

// Inheritance goes here
CHILDClass = function (childvar) { do something; };
CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
// Instance
CHILDInstance = new CHILDClass(whatever);

Oben ist irgendwie zu meiner das Erbe von JS zu verstehen. Aber ein Szenario, das ich habe keine Ahnung, wie zu implementieren, ist es das, was, wenn ich einige Initialisierung bei der Objekterstellung tun will (dh innerhalb Konstruktor) und das neue Objekt kann sofort verwendet wird .... Meine Abbildung auf Problem vielleicht nicht sein zu klar, so lassen Sie mich den folgenden C # Psuedo verwenden, um zu erklären, was ich tun mag:

class PARENT {
    public PARENT (basevar) { ... }
}
class CHILD : PARENT {
    public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
    { ... }
}

Aus irgendeinem Grund (wie init. UI-Elemente), so dass sie in Konstruktor setzen scheint der beste Weg, zu tun. Jedermann hat Idee, wie kann ich es tun.

PS: in der * 1, ich habe keine Ahnung, was ich da setzen sollte. PS2: Die oben beschriebene Situation ich die jquery.inherit Bibliothek gefunden, so kann tun, ich frage mich nur, wenn nicht Bibliothek es erreichen können. PS3: Oder mein Verständnis ist falsch. Da Javascript OOP zu mimick ist nicht beabsichtigt, (das ist, warum ich es Hack nennen), was ist die „richtige“ Logik, dies umzusetzen.

War es hilfreich?

Lösung

Es ist nicht ein Hack als solche; JavaScript ist eine prototypische Sprache, wie definiert von Wikipedia als wo:

  

.. Klassen nicht vorhanden ist, und das Verhalten Wiederverwendung (wie Vererbung in klassenbasierten Sprachen bekannt) über ein Verfahren durchgeführt wird, vorhandene Objekte von Klonen, die als Prototypen dienen.

Wie es heißt, Klassen werden nicht in JavaScript verwendet wird; Jedes Objekt, das Sie erstellen, wird von der JavaScript Object abstammen; alle Objekte in JavaScript haben die prototype Objekt und alle Instanzen von Objekten erstellen Sie ‚erben‘ Methoden und Eigenschaften von ihrem Objektprototypobjekt. Werfen Sie einen Blick auf die MDC Prototyp Referenz für weitere Informationen widersprechen.

Wie dieser, wenn Sie die Zeile nennen:

CHILDClass.prototype = new PARENTClass();

Dies ermöglicht das CHILDClass Objekt Methoden und Eigenschaften zu seinem Prototyp-Objekt aus dem PARENTClass Objekt hinzuzufügen, die auf die Idee der Vererbung in klassenbasierten einen ähnlichen Effekt wie schaffen Sprachen. Da das prototype Objekt jede Instanz des Objekts erstellt beeinflusst, dies die Methoden des übergeordneten Objekts erlaubt und Eigenschaften in jedem Fall Ihres Kind Objekt vorhanden sein.

Wenn Sie Ihre übergeordneten Klasse Konstruktor aufrufen möchten in Ihrem Kind Klasse Konstruktor verwenden Sie die call JavaScript-Funktion; Dadurch können Sie die übergeordneten Klasse Konstruktor in Zusammenhang mit der untergeordneten Klasse Konstruktor aufrufen, damit die neu prototypisiert Eigenschaften in Ihrem Kind Klasse Einstellung zu dem, was sie, wie in der übergeordneten Klasse festgelegt werden.

Sie brauchen auch nicht, etwas zu setzen, wo Sie die *1 angegeben haben, da diese Linie nur die Methoden und Eigenschaften des Kindes Klasse Prototyp-Objekt hinzuzufügen, verwendet wird; aber bedenken Sie, dass es ruft den Konstruktor der übergeordneten Klasse, also wenn es irgendwelche Argumente, die im Betrieb der übergeordneten Klasse Konstruktor von grundlegender Bedeutung sind, sollten Sie prüfen, ob diese vorhanden sind, um JavaScript-Fehler zu vermeiden.

Andere Tipps

Sie können den übergeordneten Konstruktor in der Unterklasse Konstruktor wie dies manuell aufrufen:

CHILDClass = function (basevar) {
  PARENTClass.call(this, basevar);
  // do something;
};

Der Trick hier ist die call Methode, die Sie eine Methode im Zusammenhang mit einem anderen Objekt aufrufen können. Siehe die Dokumentation von call für weitere Details.

JavaScript hat keine eingebaute Unterstützung für Vererbungshierarchien als Typ Erweiterung sollte über die Aggregation durchgeführt werden, dh gewünschte Funktionalität direkt auf das Objekt selbst oder dessen Prototyp hinzugefügt, wenn die Eigenschaft zwischen Instanzen gemeinsam genutzt werden wird.

Dennoch JS ist stark genug, um andere Formen der Objektkonstruktion möglich zu machen Umsetzung, einschließlich der klassischen Erbe.

Bei einer Klonfunktion - das ist genug ‚true‘ prototypische Vererbung hinzuzufügen, und nicht von JavaScript bastardization davon - Ihre exampe wie diese umgesetzt werden kann:

function ParentClass(baseVar) {
    // do stuff
}

// don't overwrite the prototype object if you want to keep `constructor`
// see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
ParentClass.prototype.a = 'b';
ParentClass.prototype.c = 'd';

function ChildClass(childVar) {
    // call the super constructor
    ParentClass.call(this, childVar);
}

// don't inherit from a ParentClass instance, but the actual prototype
ChildClass.prototype = clone(ParentClass.prototype);
ChildClass.prototype.e = 'f';

Es ist auch möglich, einigen syntaktischen Zucker für klassenbasierte Vererbung hinzufügen - meine eigene Implementierung hier .

Das Beispiel von oben würde dann lesen

var ParentClass = Class.extend({
    constructor: function(baseVar) {
        // do stuff
    },
    a: 'b',
    c: 'd'
});

var ChildClass = ParentClass.extend({
    e: 'f'
});

Ich habe eine leichte JavaScript OOP-Wrapper bekam die ‚Klasse-like‘ Vererbung bietet, wo man Basis Methoden außer Kraft setzen können oder Basiskonstrukteurs oder Mitglieder nennen.

Sie definieren Ihre Klassen wie folgt aus:

//Define the 'Cat' class
function Cat(catType, firstName, lastName)
{
    //Call the 'Animal' constructor.
    Cat.$baseNew.call(this, firstName, lastName);

    this.catType = catType;
}
//Extend Animal, and Register the 'Cat' type.
Cat.extend(Animal, { type: 'Cat' }, {
    hello: function(text)
    {
        return "meaoow: " + text;
    },
    getFullName: function()
    {
        //Call the base 'Animal' getFullName method.
        return this.catType + ": " + Cat.$base.getFullName.call(this);
    }
})

//It has a built-in type system that lets you do stuff like:

var cat = new Cat("ginger", "kitty", "kat");
Cat.getType()                     // "Cat"
cat.getBaseTypesAndSelf()         // ["Cat","Animal","Class"]
cat.getType()                     // "Cat"
cat.isTypeOf(Animal.getType())    // "True"

var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
dynamicCat.getBaseTypesAndSelf()  // ["Cat","Animal","Class"]
dynamicCat.getFullName()          // tab: fat cat

Quellcode verfügbar unter: Klasse. js

ich mehr Details in meinem Blog-Post über OOP in Javascript, auch haben

dachte nur, dass ich mit dem klassischen Muster einige der Probleme erwähnen würden Sie gehen für:

  1. Referenz Vars auf der Superklasse (n) wird im wesentlichen Statik für alle Instanzen zur Verfügung. Zum Beispiel, wenn Sie var arr = [1,2,3] in der Super haben, und sie instance_1.arr.push (4) instance_2.arr.push (5) alle diese Fälle werden "sehen", die Änderungen.
  2. So Sie lösen 1. mit Ayman-Lösung, die Zakas „Constructor Stealing“ nennt, aber jetzt rufen Sie den Konstruktor zweimal: einmal für Prototypen und einmal für den Konstruktor Stehlen. Lösung - für Ihren Prototyp einen Helfer wie inheritPrototype verwenden (I zeigte die gesamte Umsetzung dieser in diesem Beitrag: inheritPrototype Methode FWIW, das kam im wesentlichen aus einer Kombination von Seite 181 von Zakas Buch und einig Crockford Studie.

  3. keine Privatsphäre (aber dann wieder, müssen Sie so etwas wie die Durable Object Muster verwenden, um dies zu erhalten und das kann nicht sein, was Sie wollen)

  4. Objektdefinition links „baumelnden“: Lösung - stellt eine if-Anweisung für jede Ihrer Prototyp Funktionen überprüft und dann mit einem Prototyp wörtlichen den Prototyp definieren
  5. .

Ich habe laufen Beispiele für all dies auf Github !!!

Es war für mich nur so viel von einer Herausforderung wirklich beide grok: Zakas und Crockford Bücher über Objekterstellung und Vererbung. Ich brauchte auch einige verschiedene JavaScript TDD-Frameworks zu versuchen. Also beschloss ich, einen Aufsatz über beide TDD Frameworks und JavaScript Object Creation & Vererbung zu erstellen. Es hat Ausführen von Code und jspec Tests! Hier ist der Link: * Meine GitHub Open Source Essay / Buch

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top