Prototypen sind eine Optimierung .
Ein gutes Beispiel für eine gute Verwendung ist die jQuery-Bibliothek. Jedes Mal, wenn Sie ein jQuery-Objekt mithilfe von erhalten $('.someClass')
, verfügt dieses Objekt über Dutzende von "Methoden". Die Bibliothek könnte dies erreichen, indem sie ein Objekt zurückgibt:
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
Dies würde jedoch bedeuten, dass jedes jQuery-Objekt im Speicher immer wieder Dutzende von benannten Slots enthält, die dieselben Methoden enthalten.
Stattdessen werden diese Methoden in einem Prototyp definiert und alle jQuery-Objekte "erben" diesen Prototyp, um alle diese Methoden zu sehr geringen Laufzeitkosten zu erhalten.
Ein äußerst wichtiger Teil dessen, wie jQuery es richtig macht, ist, dass dies vor dem Programmierer verborgen ist. Es handelt sich lediglich um eine Optimierung, nicht um etwas, über das Sie sich bei der Verwendung der Bibliothek Sorgen machen müssen.
Das Problem mit JavaScript besteht darin, dass der Aufrufer bei nackten Konstruktorfunktionen daran denken muss, ihnen ein Präfix voranzustellen, new
da sie sonst normalerweise nicht funktionieren. Dafür gibt es keinen guten Grund. jQuery macht es richtig, indem es diesen Unsinn hinter einer normalen Funktion versteckt $
, sodass Sie sich nicht darum kümmern müssen, wie die Objekte implementiert werden.
Damit Sie bequem ein Objekt mit einem bestimmten Prototyp erstellen können, enthält ECMAScript 5 eine Standardfunktion Object.create
. Eine stark vereinfachte Version würde folgendermaßen aussehen:
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
Es kümmert sich nur um den Schmerz, eine Konstruktorfunktion zu schreiben und sie dann mit aufzurufen new
.
Wann würden Sie Prototypen vermeiden?
Ein nützlicher Vergleich ist mit gängigen OO-Sprachen wie Java und C #. Diese unterstützen zwei Arten der Vererbung:
- Schnittstelle Vererbung, wo Sie
implement
ein , interface
so dass die Klasse seine eigene einzigartige Implementierung für jedes Mitglied der Schnittstelle zur Verfügung stellt.
- Implementierungsvererbung , bei der Sie
extend
eine class
Standardimplementierung einiger Methoden bereitstellen.
In JavaScript ist die prototypische Vererbung eine Art Implementierungsvererbung . In Situationen, in denen Sie (in C # oder Java) von einer Basisklasse abgeleitet hätten, um ein Standardverhalten zu erhalten, an dem Sie über Überschreibungen kleine Änderungen vornehmen, ist in JavaScript eine prototypische Vererbung sinnvoll.
Wenn Sie sich jedoch in einer Situation befinden, in der Sie Schnittstellen in C # oder Java verwendet hätten, benötigen Sie in JavaScript keine bestimmte Sprachfunktion. Es ist nicht erforderlich, explizit etwas zu deklarieren, das die Schnittstelle darstellt, und Objekte müssen nicht als "Implementierung" dieser Schnittstelle markiert werden:
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
Mit anderen Worten, wenn jeder "Typ" eines Objekts seine eigenen Definitionen der "Methoden" hat, hat das Erben von einem Prototyp keinen Wert. Danach hängt es davon ab, wie viele Instanzen Sie jedem Typ zuweisen. In vielen modularen Designs gibt es jedoch nur eine Instanz eines bestimmten Typs.
Tatsächlich wurde von vielen Leuten vorgeschlagen, dass die Vererbung von Implementierungen böse ist . Das heißt, wenn es einige allgemeine Operationen für einen Typ gibt, ist es vielleicht klarer, wenn sie nicht in eine Basis- / Superklasse eingefügt werden, sondern nur als normale Funktionen in einem Modul verfügbar gemacht werden, an das Sie die Objekte übergeben. Sie möchten, dass sie operieren.
quack
Funktion in einem Prototyp befindet, mit dem die vielen Enteninstanzen verknüpft sind. 2. Die Objektliteral-Syntax{ ... }
erstellt eine Instanz (es ist nicht erforderlich, sie zu verwendennew
). 3. Wenn Sie eine Funktion JSarguments
aufrufen, wird mindestens ein Objekt im Speicher erstellt - es wird als Objekt bezeichnet und speichert die im Aufruf übergebenen Argumente: developer.mozilla.org/en/JavaScript/Reference/…Sie sollten Prototypen verwenden, wenn Sie eine "nicht statische" Methode des Objekts deklarieren möchten.
quelle
this
Beispiels definieren,this.getA = function(){alert("A")}
oder?Ein Grund für die Verwendung des integrierten
prototype
Objekts besteht darin, dass Sie ein Objekt mehrmals duplizieren, um gemeinsame Funktionen zu nutzen. Durch Anhängen von Methoden an den Prototyp können Sie beim Duplizieren von Methoden sparen, die pronew
Instanz erstellt werden. Aber wenn Sie eine Methode an die anhängenprototype
, haben alle Instanzen Zugriff auf diese Methoden.Angenommen, Sie haben eine Basisklasse
Car()
/ ein Basisobjekt.Dann erstellen Sie mehrere
Car()
Instanzen.Jetzt wissen Sie, dass jedes Auto fahren, einschalten usw. muss. Anstatt eine Methode direkt an die
Car()
Klasse anzuhängen (die pro erstellter Instanz Speicherplatz beansprucht), können Sie die Methoden stattdessen an den Prototyp anhängen (nur die Methoden erstellen) einmal), wodurch sowohl den neuenvolvo
als auch den neuen Zugang zu diesen Methoden gewährt wirdsaab
.quelle
Car.prototype = { ... }
würde, wie es ist, müsste das kommen, bevornew Car()
ich ein aufrufe, wie in dieser jsfiddle dargestellt: jsfiddle.net/mxacA . Für Ihr Argument wäre dies der richtige Weg: jsfiddle.net/Embnp . Lustige Sache ist, ich erinnere mich nicht, diese Frage beantwortet zu haben =)Fügen Sie einem Prototypobjekt Funktionen hinzu, wenn Sie viele Kopien eines bestimmten Objekttyps erstellen möchten, und alle müssen gemeinsame Verhaltensweisen aufweisen. Auf diese Weise sparen Sie Speicherplatz, indem Sie nur eine Kopie jeder Funktion haben. Dies ist jedoch nur der einfachste Vorteil.
Durch Ändern von Methoden für Prototypobjekte oder Hinzufügen von Methoden wird sofort die Art aller Instanzen der entsprechenden Typen geändert.
Warum genau Sie all diese Dinge tun würden, hängt hauptsächlich von Ihrem eigenen Anwendungsdesign und den Dingen ab, die Sie im clientseitigen Code ausführen müssen. (Eine ganz andere Geschichte wäre Code innerhalb eines Servers; viel einfacher vorstellbar, dort größeren "OO" -Code zu verwenden.)
quelle
Wenn ich in klassenbasierten Begriffen erkläre, dann ist Person Klasse, walk () ist Prototypmethode. Walk () wird also erst dann existieren, wenn Sie damit ein neues Objekt instanziieren.
Wenn Sie also Kopien von Objekten wie Person u erstellen möchten, können Sie viele Benutzer erstellen. Prototype ist eine gute Lösung, da es Speicher spart, indem für jedes Objekt im Speicher dieselbe Funktionskopie freigegeben / geerbt wird.
Während statisch in einem solchen Szenario keine große Hilfe ist.
Damit ist es eher eine Instanzmethode. Der Ansatz des Objekts ähnelt statischen Methoden.
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
quelle