In JavaScript ist jedes Objekt gleichzeitig eine Instanz und eine Klasse. Für die Vererbung können Sie eine beliebige Objektinstanz als Prototyp verwenden.
In Python, C ++ usw. gibt es Klassen und Instanzen als separate Konzepte. Um eine Vererbung durchzuführen, müssen Sie die Basisklasse verwenden, um eine neue Klasse zu erstellen, die dann zum Erstellen abgeleiteter Instanzen verwendet werden kann.
Warum ist JavaScript in diese Richtung gegangen (prototypbasierte Objektorientierung)? Was sind die Vor- und Nachteile von prototypbasiertem OO gegenüber herkömmlichem klassenbasiertem OO?
javascript
oop
inheritance
prototype-programming
Stefano Borini
quelle
quelle
GEB
?Antworten:
Hier gibt es ungefähr hundert Terminologieprobleme, die sich hauptsächlich um jemanden (nicht Sie) drehen, der versucht, seine Idee wie The Best klingen zu lassen.
Alle objektorientierten Sprachen müssen mit verschiedenen Konzepten umgehen können:
Nun zum Vergleich:
Das erste ist die ganze Frage "Klasse" gegen "Prototyp". Die Idee begann ursprünglich in Simula, wo mit einer klassenbasierten Methode jede Klasse eine Reihe von Objekten darstellte, die denselben Zustandsraum (lesen Sie "mögliche Werte") und dieselben Operationen gemeinsam hatten, wodurch eine Äquivalenzklasse gebildet wurde. Wenn Sie auf Smalltalk zurückblicken, da Sie eine Klasse öffnen und Methoden hinzufügen können, entspricht dies praktisch dem, was Sie in Javascript tun können.
Später wollten OO-Sprachen die statische Typprüfung verwenden können, daher kamen wir auf die Idee einer festen Klasse, die zur Kompilierungszeit festgelegt wurde. In der Open-Class-Version hatten Sie mehr Flexibilität. In der neueren Version hatten Sie die Möglichkeit, einige Arten von Korrektheit am Compiler zu überprüfen, die andernfalls getestet worden wären.
In einer "klassenbasierten" Sprache erfolgt das Kopieren zur Kompilierungszeit. In einer Prototypsprache werden die Operationen in der Prototypdatenstruktur gespeichert, die zur Laufzeit kopiert und geändert wird. Abstrakt ist eine Klasse jedoch immer noch die Äquivalenzklasse aller Objekte, die denselben Zustandsraum und dieselben Methoden verwenden. Wenn Sie dem Prototyp eine Methode hinzufügen, erstellen Sie effektiv ein Element einer neuen Äquivalenzklasse.
Warum das? in erster Linie, weil es zur Laufzeit einen einfachen, logischen und eleganten Mechanismus ergibt. Um ein neues Objekt oder eine neue Klasse zu erstellen, müssen Sie lediglich eine Tiefenkopie durchführen und alle Daten und die Prototypdatenstruktur kopieren. Vererbung und Polymorphismus erhalten Sie dann mehr oder weniger kostenlos: Die Methodensuche besteht immer darin, ein Wörterbuch nach einer Methodenimplementierung nach Namen zu fragen.
Der Grund, warum wir in Javascript / ECMA-Skripten gelandet sind, ist im Grunde, dass wir uns vor 10 Jahren mit viel weniger leistungsfähigen Computern und viel weniger ausgefeilten Browsern befasst haben. Durch die Wahl der prototypbasierten Methode konnte der Interpreter sehr einfach sein und gleichzeitig die gewünschten Eigenschaften der Objektorientierung beibehalten.
quelle
Ein Vergleich, der leicht auf den prototypenbasierten Ansatz ausgerichtet ist, findet sich in der Arbeit Self: The Power of Simplicity . Das Papier macht die folgenden Argumente für Prototypen:
Self ist wahrscheinlich die erste Sprache, die Prototypen implementiert (sie hat auch andere interessante Technologien wie JIT entwickelt, die später in die JVM aufgenommen wurden). Daher sollte das Lesen der anderen Self-Artikel ebenfalls lehrreich sein.
quelle
point
ist a eine Instanz der KlassePoint
, eine Instanz der Metaklassestandard-class
, die eine Instanz von sich selbst ist, ad finitum.Sie sollten sich ein großartiges Buch über JavaScript von Douglas Crockford ansehen . Es bietet eine sehr gute Erklärung für einige der Entwurfsentscheidungen, die von JavaScript-Erstellern getroffen wurden.
Einer der wichtigen Designaspekte von JavaScript ist das prototypische Vererbungssystem. Objekte sind in JavaScript erstklassige Bürger, so dass reguläre Funktionen auch als Objekte implementiert werden (genauer gesagt 'Function'-Objekt). Meiner Meinung nach sollte es, als es ursprünglich für die Ausführung in einem Browser entwickelt wurde, zum Erstellen vieler Singleton-Objekte verwendet werden. Im Browser-DOM finden Sie in diesem Fenster, Dokument usw. alle Singleton-Objekte. Außerdem ist JavaScript eine lose typisierte dynamische Sprache (im Gegensatz zu Python, eine stark typisierte dynamische Sprache). Daher wurde ein Konzept der Objekterweiterung mithilfe der Eigenschaft 'Prototyp' implementiert.
Ich denke, es gibt einige Profis für prototypbasierte OO, wie sie in JavaScript implementiert sind:
Hier sind einige der Nachteile von prototypischem OO:
quelle