Mehrfache Vererbung/Prototypen in JavaScript
Ich komme zu einem Punkt, wo ich brauche eine Art rudimentäre Mehrfachvererbung geschieht in JavaScript. (Ich bin nicht hier, um zu diskutieren, ob das eine gute Idee ist oder nicht, also bitte bitte halten Sie die Kommentare für sich.)
Ich möchte nur wissen, wenn jemand versucht, dies mit allen (oder auch nicht) Erfolg, und wie ging es.
Kochen es nach unten, was ich wirklich brauchen, ist in der Lage, ein Objekt, das fähig ist, erbt ein Objekt von mehr als ein Prototyp Kette (d.h. jeder Prototyp haben könnte, seine eigene Kette), aber in einer bestimmten Reihenfolge (es wird durchsuchen Sie die Ketten, um für die erste definition).
Zu zeigen, wie dies theoretisch möglich ist, es könnte erreicht werden, indem die Befestigung der sekundären Kette an das Ende der primären Kette, aber würde dieses wirken sich auf alle Instanzen dieser früheren Prototypen und das ist nicht das, was ich will.
Gedanken?
Geben Sie einen Blick zu TraitsJS (link 1, link 2) ist es eine wirklich gute alternative zu Mehrfachvererbung und Mixins in Verbindung...
denn das ist nicht sehr dynamisch. Ich möchte in der Lage zu pick-up-änderungen in einer der beiden übergeordneten Kette, wie Sie auftreten. Aber das heißt, ich kann darauf zurückgreifen, wenn es gerade nicht möglich ist.
möglich, Duplikat der führt javascript-Unterstützung Mehrfachvererbung wie C++
Eine interessante Lektüre dazu: webreflection.blogspot.co.uk/2009/06/...
InformationsquelleAutor devios1 | 2012-02-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mehrfache Vererbung kann erreicht werden in ECMAScript 6 durch die Verwendung Proxy-Objekte.
Implementierung
Erklärung
Ein proxy-Objekt besteht aus einem Zielobjekt und einige fallen, die definieren, benutzerdefinierte Verhalten für grundlegende Operationen.
Beim erstellen ein Objekt erbt von einem anderen, verwenden wir
Object.create(obj)
. Aber in diesem Fall wollen wir die mehrfache Vererbung, also stattobj
ich benutze einen proxy, redirect grundlegende Operationen auf das entsprechende Objekt.Ich benutze diese fallen:
- Falle ist eine Falle für die
in
- operator. Ich benutzezu überprüfen, wenn mindestens ein Prototyp enthält die Eigenschaft.
get
- Falle ist eine Falle für die erste Immobilien-Werte. Ich benutzezu finden, der erste Prototyp enthält, die Eigenschaft, und ich geben den Wert zurück, oder rufen Sie die get-Methode an die entsprechenden Empfänger. Dies erfolgt durch
Reflektieren.get
. Wenn kein Prototyp enthält die Eigenschaft, die ich zurückundefined
.set
- Falle ist eine Falle für die Einstellung der Eigenschaft Werte. Ich benutzezu finden, der erste Prototyp enthält, die Eigenschaft, und ich nenne Ihren setter auf die entsprechenden Empfänger. Wenn es keine setter oder kein Prototyp enthält die Eigenschaft den Wert definiert ist, auf die entsprechenden Empfänger. Dies erfolgt durch
Reflektieren.set
.aufzählen
- Falle ist eine Falle fürfor...in
- Schleifen. Ich iterieren aufzählbare Eigenschaften aus dem ersten Prototyp, der dann von der zweiten, und so weiter. Sobald eine Eigenschaft wurde iteriert, Speichere ich es in einer hash-Tabelle zu vermeiden, Durchlaufen Sie erneut.Warnung: Diese Falle wurde entfernt ES7 Entwurf und veraltet ist, im Browser.
ownKeys
- Falle ist eine Falle für- Objekt.getOwnPropertyNames()
. Da ES7,for...in
Schleifen halten ruft [[GetPrototypeOf]] und die Eigenschaften von jedem. Also, um es Durchlaufen, werden die Eigenschaften der Prototypen, ich benutze diese Falle zu machen, alle aufzählbaren Eigenschaften geerbt erscheinen wie eigene Eigenschaften.getOwnPropertyDescriptor
- Falle ist eine Falle für- Objekt.getOwnPropertyDescriptor()
. Alle aufzählbaren Eigenschaften angezeigt, wie die eigenen Eigenschaften in derownKeys
Falle ist nicht genug,for...in
Schleifen erhalten Sie den Deskriptor zu überprüfen, ob Sie Durchlaufen werden. Also ich benutzezu finden, der erste Prototyp enthält, die Eigenschaft, und ich Durchlaufen, seine prototypische Kette, bis ich den Eigentümer, und ich, wieder in seine Deskriptor. Wenn kein Prototyp enthält die Eigenschaft, die ich zurück
undefined
. Der Deskriptor wird geändert, um es konfigurierbar, sonst könnte es brechen einige proxy-Invarianten.preventExtensions
unddefineProperty
fallen sind nur enthalten, um zu verhindern, dass diese Operationen ändern die proxy-Ziel. Sonst könnten wir am Ende brechen einige proxy-Invarianten.Gibt es mehr fallen zur Verfügung, die ich nicht verwenden
getPrototypeOf
- Falle Hinzugefügt werden könnten, aber es gibt keinen richtigen Weg, um die Rückkehr der mehreren Prototypen. Dies impliziertinstanceof
wird nicht funktionieren weder. Daher lass ich es bekommen, dem Prototyp der Gegner, welche zunächst null ist.setPrototypeOf
- Falle Hinzugefügt werden könnten und akzeptieren ein array von Objekten, die würde an die Stelle der Prototypen. Dies bleibt als übung für den Leser. Hier ich lass es einfach ändern Sie den Prototyp der Zielgruppe, die nicht sehr nützlich, weil keine Falle verwendet das Ziel.deleteProperty
- Falle ist eine Falle für das löschen von eigenen Eigenschaften. Der proxy stellt die Vererbung, so würde dies nicht viel Sinn. Ich lasse Sie versuchen, das löschen auf dem Ziel, das sollte keine Eigenschaft besitzen, sowieso.isExtensible
- Falle ist eine Falle für die Erweiterbarkeit. Nicht sehr nützlich, da eine invariante Kräfte, bis Sie wieder die gleiche Dehnbarkeit wie das Ziel. Also ich lass es einfach leiten den Betrieb, um das Ziel, die erweiterbar sein.apply
undKonstrukt
fallen sind fallen für den Aufruf oder instanziieren. Sie sind nur sinnvoll, wenn das Ziel ist, eine Funktion oder einen Konstruktor.Beispiel
Es wird langsamer sein als die Daten-Eigenschaften in ein normales Objekt, aber ich glaube nicht, es wird noch viel schlimmer, als accessor-Eigenschaften.
TIL:
multiInherit(o1={a:1}, o2={b:2}, o3={a:3, b:3})
Ich würde erwägen, den Austausch "Multiple inheritance" durch "Mehrfach-delegation" zu erhalten eine bessere Idee von, was Los ist. Der Schlüssel Konzept in Ihrer Umsetzung sein, dass der proxy ist eigentlich die Wahl das richtige Objekt für delegieren (oder Weiterleitung) der Nachricht. Die Kraft deiner Lösung ist, dass Sie können erweitern die Ziel-Prototyp/s dynamisch. Andere Antworten sind, mit Verkettung (ala
Object.assign
) oder sich eine ganz andere Grafik, in der end-alle von Ihnen sind ein-ein-nur Prototyp-Kette zwischen den Objekten. Die proxy-Lösung bietet eine runtime-Verzweigung, und diese Felsen!Über die Leistung, wenn Sie ein Objekt erstellen, die erbt von mehreren Objekten, die Erben von mehreren Objekten, und so weiter, dann wird es exponentiell. Also ja, es wird langsamer. Aber in normalen Fällen, ich glaube nicht, dass es schlimm ist.
InformationsquelleAutor Oriol
Update (2019): Der original-post ist schon ziemlich veraltet. Dieser Artikel (jetzt internet-archive link, da domain-ging) und seine zugehörigen GitHub-Bibliothek sind eine gute, moderne Ansatz.
Original post:
Mehrfachvererbung [Bearbeiten keine richtige Vererbung von Typ, sondern von Eigenschaften; Mixins in Verbindung] in Javascript ist ziemlich einfach, wenn Sie konstruierten Prototypen eher als generisches-Objekt ersetzt. Hier sind zwei übergeordneten Klassen Erben von:
Hinweis, ich habe das gleiche "name" - Mitglied in jedem Fall, das könnte ein problem werden, wenn die Eltern sich nicht einig darüber, wie "name" sollte behandelt werden. Aber Sie sind kompatibel (redundant, wirklich) in diesem Fall.
Jetzt brauchen wir nur noch eine Klasse, die erbt von beiden. Die Vererbung erfolgt durch nennening die Konstruktor-Funktion (ohne Verwendung des new-Schlüsselwort) für die Prototypen und die Objekt-Konstruktoren. Erste, der Prototyp hat die Vererbung von der übergeordneten Prototypen
Und der Konstruktor hat die Vererbung von der übergeordneten Konstruktoren:
Nun können Sie wachsen, Essen, und die Ernte der verschiedenen Instanzen:
Ich glaube nicht, dass die eingebauten Prototypen haben Konstruktoren, die Sie anrufen können.
Gut, ich kann
Array.call(...)
aber es scheint nicht zu beeinflussen, was auch immer ich pass dathis
.Sie konnte tun
Array.prototype.constructor.call()
Vielen Dank für das lassen mich wissen. Habe ich ersetzt den link mit einem link auf die archivierte web-Seite.
InformationsquelleAutor Roy J
Ich wie John Resig die Implementierung einer Klasse-Struktur: http://ejohn.org/blog/simple-javascript-inheritance/
Diese können einfach erweitert, um so etwas wie:
denen Sie übergeben mehrere Objekte an die Erben. Sie gehen zu verlieren
instanceOf
Fähigkeit hier, aber das ist gegeben, wenn Sie möchten, die mehrfache Vererbung.meine ziemlich verworrenes Beispiel oben ist erhältlich bei https://github.com/cwolves/Fetch/blob/master/support/plugins/klass/klass.js
Beachten Sie, dass es einige tote code in diese Datei, aber es erlaubt Mehrfachvererbung, wenn Sie möchten, um einen Blick zu nehmen.
Wenn Sie möchten, angekettet Vererbung (KEINE Mehrfachvererbung, aber für die meisten Menschen ist es das gleiche), es kann erreicht werden mit der Klasse wie:
die Erhaltung der ursprünglichen Prototyp-Kette, aber Sie haben auch eine Menge von sinnlosen code laufen.
True, aber wenn Sie wollen, "Mehrfachvererbung", die eine Klasse wird von zwei Klassen, es gibt nicht wirklich eine alternative. Geändert Antwort zu reflektieren, dass einfach die Verkettung Klassen gemeinsam ist die gleiche Sache in den meisten Fällen.
Es scheint Ihr GitHUb verschwunden ist haben Sie noch github.com/cwolves/Fetch/blob/master/support/plugins/klass/... ich würde nicht dagegen, es zu betrachten, wenn Sie sich zu teilen?
InformationsquelleAutor Mark Kahn
Diese nutzt
Object.create
um einen echten Prototyp-Kette:Beispiel:
zurück:
so, dass
obj.a === 1
,obj.b === 3
usw.es lohnt sich, diesem Artikel aus, wenn Sie suchen in Unterklassen von arrays; es könnte sparen Sie einige Kopfschmerzen. viel Glück!
InformationsquelleAutor pimvdb
Nicht bekommen zu verwechseln mit dem JavaScript-framework-Implementierungen von mehrfach-Vererbung.
Alles, was Sie tun müssen, ist Objekt.create() ein neues Objekt erstellen jedes mal, wenn mit dem angegebenen Prototyp-Objekt und Eigenschaften, dann ändern Sie die Objekt.der Prototyp.Konstruktor jeden Schritt des Weges, wenn Sie planen, auf die Instanziierung
B
in die Zukunft.Erben Instanz Eigenschaften
thisA
undthisB
wir verwenden Funktion.der Prototyp.call() am Ende jeder Objekt-Funktion. Dies ist optional, wenn Sie nur die Sorge um Erben der Prototyp.Führen Sie den folgenden code irgendwo und beobachten
objC
:B
erbt der Prototyp vonA
C
erbt der Prototyp vonB
objC
ist eine Instanz vonC
Dies ist eine gute Erklärung der Schritte oben:
OOP In JavaScript: Was Sie Wissen MÜSSEN
InformationsquelleAutor Dave
Ich bin in keiner Weise ein Experte auf javascript-OOP, aber wenn ich Sie richtig verstehe, Sie wollen so etwas wie (pseudo-code):
In diesem Fall, würde ich versuchen so etwas wie:
c.prototype
mehrere Male nicht Ertrag mehrere Prototypen. Zum Beispiel, wenn Sie hatteAnimal.isAlive = true
,Cat.isAlive
wäre noch nicht definiert.Ja, ich war was bedeutet, zu mischen, zu den Prototypen, korrigiert... (ich habe die jQuery erweitern hier, aber Sie erhalten das Bild)
InformationsquelleAutor David Hellsing
Ist es möglich zu implementieren, die mehrfache Vererbung in JavaScript, aber nur sehr wenige Bibliotheken, die es tut.
Konnte ich zeigen Ring.js, das einzige Beispiel das ich kenne.
InformationsquelleAutor nicolas-van
Ich daran heute viel und versuchen, zu erreichen, das mich in ES6. Wie ich es Tat, war es mit Browserify, Babel und dann getestet habe ich es mit Wallaby und es schien zu funktionieren. Mein Ziel ist das erweitern der aktuelle Array, gehören ES6, ES7, und fügen Sie einige zusätzliche benutzerdefinierte Funktionen, die ich brauche in der Prototyp für den Umgang mit audio-Daten.
Wallaby geht 4 meines tests. Die example.js -Datei eingefügt werden kann in der Konsole und Sie können sehen, dass die 'includes' - Eigenschaft ist der Prototyp der Klasse. Ich will noch testen, das morgen mehr.
Hier ist meine Methode: (ich werde wahrscheinlich umgestalten, und Verpacken Sie das Modul nach etwas Schlaf!)
Github-Repo:
https://github.com/danieldram/array-includes-polyfill
InformationsquelleAutor Daniel Ram
Ich denke, es ist lächerlich einfach. Das Problem hier ist, dass das Kind die Klasse wird beziehen sich nur auf
instanceof
für die erste Klasse Sie nennenhttps://jsfiddle.net/1033xzyt/19/
InformationsquelleAutor BarryBones41
Sich das Paket IeUnit.
Das Konzept der assimilation umgesetzt IeUnit scheint bietet, was Sie suchen in einer sehr dynamischen Art und Weise.
InformationsquelleAutor James
Hier ist ein Beispiel von Prototyp Verkettung mit Konstruktor-Funktionen:
Dieses Konzept verwendet Yehuda Katz-definition eines "Klasse" für JavaScript:
Im Gegensatz zu den Objekt.erstellen Konzept, wenn die Klassen sind so aufgebaut, und wir wollen Sie zum erstellen von Instanzen einer "Klasse", wir brauchen nicht zu wissen, was jeder "Klasse" erbt von. Wir verwenden nur
new
.Die Reihenfolge der precendence sollte Sinn machen. Zunächst sieht es in der Instanz-Objekt, dann ist es der Prototyp, dann der nächste Prototyp, etc.
Wir können auch ändern, den Prototypen wird die Wirkung aller Objekte gebaut, die auf die Klasse.
Ursprünglich schrieb ich einige dieser mit diese Antwort.
child
erbt vonparent1
undparent2
). Dein Beispiel spricht nur über eine Kette.InformationsquelleAutor Luke
Ein Nachzügler in der Szene ist SimpleDeclare. Allerdings, beim Umgang mit mehrfacher Vererbung werden Sie noch am Ende mit Kopien der original-Konstruktoren. Das ist eine Notwendigkeit in Javascript...
Merc.
Proxies sind interessant! Ich werde definitiv Blick auf die Veränderung der SimpleDeclare, so dass Sie nicht brauchen, um zu kopieren Methoden über die Verwendung von proxies, wenn Sie erst einmal Teil des Standards. SimpleDeclare code ist wirklich, wirklich einfach zu Lesen und zu ändern...
InformationsquelleAutor Merc
Ich würde ds.oop. Seine ähnlich prototype.js und andere. macht mehrfache Vererbung sehr einfach, und seine minimalistisch. (nur 2 oder 3 kb) unterstützt Auch einige andere nette features wie Schnittstellen und dependency injection
InformationsquelleAutor dss