Bitte vergessen Sie alle objektorientierten Wissen, die Sie zuvor gelernt haben. Betrachten Sie einfach die Rennsituation hier. Ja, es ist Rennen.
Vor kurzem schaue ich 24 Stunden Le Mans an, ein beliebtes Ereignis in Frankreich. Das schnellste Auto heißt Le Mans -Prototyp. Obwohl diese Autos von Herstellern wie "Audi" oder "Peugeot" hergestellt werden, sind sie nicht die Art von Autos, die Sie auf der Straße oder auf der Autobahn sehen. Sie werden speziell für Hochgeschwindigkeitsdauerveranstaltungen gemacht.
Der Hersteller investiert enorme Geldbeträge, um diese Prototyp -Autos zu entwickeln, zu entwerfen und herzustellen, und Ingenieure versuchen immer, dieses Projekt extrem zu machen. Sie führten verschiedene Experimente an Legierungen, Biokraftstücken, Bremstechnologie, Zusammensetzung und Sicherheitsmerkmalen von Reifen durch. Im Laufe der Zeit wurden einige der Techniken in diesen Experimenten wiederholt verbessert und in die Mainstream -Produktlinie von Fahrzeugen eingegeben. Ein Teil der Technologie im Fahrzeug, mit dem Sie fahren, wurden möglicherweise im Rennprototyp debütiert.
Sie können auch sagen, dass diese Mainstream -Fahrzeuge die technischen Prototypen von Rennwagen erben .
Bisher haben wir die Grundlage für die Erörterung des Prototyps und der Erbschaftsprobleme in JavaScript. Es ist zwar nicht so gut wie das klassische Vererbungsmuster, das Sie in C ++, Java oder C#kennen, aber es ist genauso leistungsfähig und potenziell flexibler.
JavaScript ist voll von Objekten, die sich auf Objekte im traditionellen Sinne beziehen, dh einer einzigen Einheit, die Zustand und Verhalten enthält. Beispielsweise ist ein Array in JavaScript ein Objekt, das mehrere Werte enthält und Push-, Reverse- und POP -Methoden enthält.
var myarray = [1, 2]; myarray.push (3); myarray.reverse (); myarray.pop (); var länge = myarray.length;
Nun ist die Frage, woher kommt der Druck? Die statischen Sprachen, die wir früher erwähnt haben, verwenden "Klassensyntax", um die Struktur von Objekten zu definieren. JavaScript ist jedoch eine Sprache ohne "Klassensyntax" und kann jedes Array -Objekt nicht mit der Syntax der Array -Klasse "Klasse" definieren. Und weil JavaScript eine dynamische Sprache ist, können wir Methoden für Objekte platzieren, sobald wir sie benötigen. Beispielsweise definiert der folgende Code ein Punktobjekt, das verwendet wird, um einen Punkt im zweidimensionalen Raum darzustellen, und definiert auch eine Add-Methode.
var point = {x: 10, y: 5, add: function (otherpoint) {this.x += otherpoint.x; this.y += otherpoint.y; }};Die obigen Praktiken sind jedoch nicht sehr skalierbar. Wir müssen sicherstellen, dass jedes Punktobjekt eine Methode hinzufügen, und möchten auch, dass alle Punktobjekte die Implementierung derselben Add -Methode teilen, anstatt diese Methode manuell zu jedem Punktobjekt hinzuzufügen. Hier kommt der Prototyp ins Spiel.
In JavaScript bleibt jedes Objekt verborgen - ein Verweis auf ein anderes Objekt, auch als Prototyp bezeichnet. Das Array, das wir zuvor erstellt haben, verweist auf ein Prototypobjekt, ebenso wie die Punktobjekte, die wir selbst erstellt haben. Wie oben erwähnt, sind Prototypreferenzen versteckt, aber es gibt auch Implementierungen von ECMAScript (den offiziellen Namen von JavaScript), die über das Attribut eines Objekts __Proto__ auf diese Prototypreferenz zugreifen können (z. B. Google Chrome). Konzeptionell können wir Objekte als Beziehungen behandeln, die denen in Abbildung 1-Prototyp ähneln.
Abbildung 1
Mit Blick auf die Zukunft können Entwickler das Objekt verwenden. Zum Zeitpunkt des Schreibens dieses Artikels kann das Object.getPrototypeof -Funktion bereits in Google Chrome, Firefox und IE9 -Browsern verwendet werden. Weitere Browser werden diese Funktion in Zukunft implementieren, da es bereits Teil des ECMAScript -Standards ist. Wir können den folgenden Code verwenden, um zu beweisen, dass die von uns erstellten MyArray- und DOT -Objekte auf zwei verschiedene Prototypobjekte beziehen.
Für den Rest dieses Artikels werde ich die Funktionen __Proto und Object.getPrototypeof-Funktionen verwenden, vor allem, weil __Proto__ in Diagramme und Sätzen einfacher zu identifizieren ist. Es sollte daran erinnert werden, dass es (__Proto__) nicht der Standard ist, und das Object.getPrototypeOf -Funktion ist die empfohlene Methode zum Anzeigen von Objektprototypen.
Was macht den Prototyp so besonders?
Wir haben diese Frage nicht beantwortet: Woher kommt ein Array in ein Array? Die Antwort lautet: Es kommt aus dem MyArray -Prototyp -Objekt. Abbildung 2 ist ein Screenshot des Skript -Debuggers in Chrome. Wir haben das Object.getPrototypeof -Methode bezeichnet, um das Prototyp -Objekt von MyArray anzuzeigen.
Abbildung 2
Beachten Sie, dass es in MyArrays Prototyp -Objekt viele Methoden gibt, einschließlich der genannten Push-, Pop- und Reverse -Methoden in Code -Beispielen. Daher enthält die Push -Methode das Prototyp -Objekt, aber wie bezieht sich die MyArray -Methode darauf?
myarray.push (3);
Der erste Schritt zum Verständnis, wie es funktioniert, besteht darin, zu erkennen, dass der Prototyp nicht etwas Besonderes ist. Der Prototyp ist nur ein normales Objekt. Sie können dem Prototyp Methoden und Eigenschaften hinzufügen und sie als andere JavaScript -Objekte behandeln. Um die Aussage von "Schwein" in George Orwells Roman "Animal Farm" anzuwenden - sollten alle Objekte gleich sein, aber einige Objekte (diejenigen, die die Regeln befolgen) sind gleichermaßen als andere.
Prototypobjekte in JavaScript sind in der Tat besonders, da sie den folgenden Regeln befolgen. Wenn wir JavaScript mitteilen, dass wir die Push -Methode eines Objekts aufrufen oder die X -Eigenschaft des Objekts lesen möchten, sucht die Laufzeit zunächst nach dem Objekt selbst. Wenn die Laufzeit nicht finden kann, was sie will, folgt sie dem __Proto__ -Referenz- und Objektprototyp, um nach dem Mitglied zu suchen. Wenn wir MyArrays Push -Methode nennen, findet JavaScript die Push -Methode im MyArray -Objekt nicht, sondern auf dem Prototyp -Objekt von MyArray, so dass JavaScript diese Methode aufruft (siehe Abbildung 3).
Abbildung 3
Das oben beschriebene Verhalten bezieht sich auf ein Objekt selbst, das eine Methode oder Eigenschaft im Prototyp erbt. In JavaScript wird die Vererbung tatsächlich ohne Verwendung der Klassensyntax erreicht. Genau wie bei einem Auto, das die entsprechende Technologie eines Rennprototyps erbt, kann ein JavaScript -Objekt auch funktionale Merkmale eines Prototyp -Objekts erben.
Abbildung 3 zeigt auch, dass jedes Array -Objekt auch seinen eigenen Zustand und seine eigenen Mitglieder aufrechterhalten kann. Bei der Anforderung des Längenattributs von MyArray erhält JavaScript den Wert des Längenattributs in MyArray, ohne den entsprechenden Wert im Prototyp zu lesen. Wir können die Push -Methode "überschreiben", indem wir eine Methode wie Push zum Objekt hinzufügen. Dadurch wird die Push -Methode -Implementierung im Prototyp effektiv ausgeblendet.
Die wirkliche Magie von Prototypen in JavaScript ist, wie mehrere Objekte Verweise auf dasselbe Prototyp -Objekt aufrechterhalten. Zum Beispiel, wenn wir zwei Arrays wie diese erstellen:
var myarray = [1, 2]; var yourArray = [4, 5, 6];
Anschließend teilen diese beiden Arrays das gleiche Prototyp -Objekt, und der folgende Code bewertet TRUE:
Object.getPrototypeof (myArray) === Object.getPrototypeof (YourArray);
Wenn wir uns auf die Push -Methode auf zwei Array -Objekten beziehen, sucht JavaScript nach der Push -Methode, die im Prototyp gemeinsam genutzt wird.
Abbildung 4
Prototypobjekte in JavaScript liefern Vererbungsfunktionen, und gleichzeitig wird die Freigabe dieser Methode implementiert. Der Prototyp ist ebenfalls gekettet. Mit anderen Worten, da ein Prototypobjekt nur ein Objekt ist, kann ein Prototypobjekt auf eine Verweise auf ein anderes Prototypobjekt aufrechterhalten werden. Wenn Sie Abbildung 2 noch einmal besuchen, können Sie sehen, dass die __Proto__-Eigenschaft des Prototyps ein Nicht-Null-Wert ist, der auf einen anderen Prototyp hinweist. Wenn JavaScript nach Mitgliedern wie der Push -Methode sucht, überprüft es jedes Objekt entlang der Prototyp -Referenzkette, bis sie gefunden wird, oder das Ende der Prototypkette erreicht. Prototyp -Ketten eröffnen einen flexiblen Pfad für Vererbung und Teilen.
Die nächste Frage, die Sie sich stellen könnten, lautet: Wie richte ich Prototyp -Verweise auf diese benutzerdefinierten Objekte ein? Wie kann ich beispielsweise das zuvor verwendete Punktobjekt zum Prototyp -Objekt hinzufügen und die Methode von mehreren Punktobjekten von mehreren Punktobjekten erben? Bevor wir diese Frage beantworten, müssen wir uns die Funktionen ansehen.
Funktionen in JavaScript sind auch Objekte. Eine solche Erklärung bringt mehrere wichtige Ergebnisse mit sich, und wir werden nicht alle Angelegenheiten in diesem Artikel behandeln. Unter ihnen ist die Fähigkeit, einer Variablen eine Funktion zuzuweisen und eine Funktion als Parameter an eine andere Funktion zu übergeben, das grundlegende Paradigma des modernen JavaScript -Programmierausdrucks.
Wir müssen darauf achten, dass die Funktion selbst ein Objekt ist, sodass die Funktion ihre eigenen Methoden, Eigenschaften und ein Prototypobjekt verweisen kann. Lassen Sie uns die Bedeutung des folgenden Codes diskutieren.
// Dies wird true zurückgegeben: typeof (array) === "Funktion" // Ein solcher Ausdruck ist auch: Object.getPrototypeof (Array) === Object.getPrototypeof (function () {}) // Ein solcher Ausdruck ist derselbe: Array.Prototype! = NullDie erste Zeile im Code zeigt, dass das Array in JavaScript eine Funktion ist. Wir werden sehen, wie Sie die Array -Funktion aufrufen, um ein neues Array -Objekt zu erstellen. Die nächste Codezeile beweist, dass das Array -Objekt denselben Prototyp wie jedes andere Funktionsobjekt verwendet, genau wie wir sehen, dass derselbe Prototyp zwischen Array -Objekten gemeinsam genutzt wird. Die letzte Codezeile beweist, dass die Array -Funktion eine Prototyp -Eigenschaft hat und diese Prototyp -Eigenschaft auf ein gültiges Objekt zeigt. Diese Prototyp -Eigenschaft ist sehr wichtig.
Jedes Funktionsobjekt in JavaScript verfügt über eine Prototyp -Eigenschaft. Verwechseln Sie niemals das __Proto__ -Attribut dieser Prototyp -Eigenschaft. Sie sind von unterschiedlichem Zweck und verweisen auch nicht auf dasselbe Objekt.
// trueObject.getPrototypeof (Array)! = Array.Prototype zurückgeben
Array .__ Proto__ bietet einen Array -Prototyp. Bitte behandeln Sie es als ein von der Array -Funktion geerbter Objekt.
Array.Protoype bietet Prototypobjekte für alle Arrays. Das heißt, es liefert Prototypobjekte von Array -Objekten wie Myarray und enthält auch Methoden, die alle Arrays erben werden. Wir können einen Code schreiben, um diese Tatsache zu beweisen.
// Truearray.Prototype == Object.getPrototypeof (myArray) // Es ist auch Truearray.Prototype == Object.getPrototypeof (YourArray);
Wir können dieses neue Wissen auch nutzen, um das vorherige Diagramm neu zu streichen.
Abbildung 5
Stellen Sie sich basierend auf dem, was Sie wissen, den Prozess der Erstellung eines neuen Objekts vor und verhalten das neue Objekt wie ein Array. Eine Möglichkeit besteht darin, den folgenden Code zu verwenden.
// Erstellen Sie ein neues leeres Objekt var o = {}; // aus demselben Prototyp geerbt.Obwohl dieser Code interessant ist und funktioniert, ist das Problem, dass nicht jede JavaScript -Umgebung beschreibbare __Proto__ -Objekteigenschaften unterstützt. Glücklicherweise verfügt JavaScript über einen Standardmechanismus zum Erstellen von Objekten. Ein Bediener muss nur neue Objekte erstellen und die __Proto__ -Referenz des neuen Objekts festlegen, dh der "neue" Bediener.
var o = new array (); o.push (3);
Der neue Bediener in JavaScript hat drei grundlegende Aufgaben. Erstens erzeugt es ein neues leeres Objekt. Als nächstes setzt es die Eigenschaft __Proto__ des neuen Objekts so, dass sie den Prototyp -Eigenschaften der aufgerufenen Funktion entsprechen. Schließlich ruft der Bediener die Funktion auf und übergibt das neue Objekt als "diese" Referenz. Wenn Sie die letzten beiden Codezeilen erweitern möchten, wird dies zur folgenden Situation:
var o = {}; o .__ proto__ = array.prototype; array.call (o); o.push (3);Mit der Aufrufmethode der Funktion können Sie das von "Dies" in der Funktion verwiesene Objekt beim Aufrufen der Funktion angeben. Natürlich muss der Autor der Funktion eine solche Funktion in diesem Fall implementieren. Sobald der Autor eine solche Funktion erstellt hat, kann er als Konstruktor bezeichnet werden.
Konstruktor
Konstruktoren entsprechen den normalen Funktionen, haben jedoch die folgenden zwei besonderen Eigenschaften.
Array ist ein Beispiel für einen Konstruktor. Die Array -Funktion muss mit dem neuen Bediener verwendet werden, und das erste Array -Buchstaben wird aktiviert. JavaScript enthält Array als integrierte Funktion, und jeder kann seinen eigenen Konstruktor schreiben. Tatsächlich können wir endlich einen Konstruktor für die zuvor erstellten Punktobjekte schreiben.
var point = function (x, y) {this.x = x; this.y = y; this.add = function (otherpoint) {this.x += otherpoint.x; this.y += otherpoint.y; }} var p1 = neuer Punkt (3, 4); var p2 = neuer Punkt (8, 6); p1.add (p2);Im obigen Code verwenden wir den neuen Operator und die Punktfunktion, um ein Punktobjekt zu erstellen, das die X- und Y -Attribute und eine Methode hinzufügen. Sie können sich das Endergebnis vorstellen, wie in Abbildung 6 gezeigt.
Abbildung 6
Das Problem ist nun, dass in jedem unserer Punktobjekte immer noch eine separate Methode hinzufügen. Mit dem von uns gelernten Prototyp und Vererbung übertragen wir die Add -Methode des Punktobjekts aus jeder Punktinstanz in Punkt.Prototyp. Um den Effekt der Erben der ADD -Methode zu erreichen, müssen wir lediglich den Punkt des Punktes ändern.
var point = function (x, y) {this.x = x; this.y = y;} point.prototype.add = function (otherpoint) {this.x += otherpoint.x; this.y += otherpoint.y;} var p1 = neuer Punkt (3, 4); var p2 = neuer Punkt (8, 6); p1.add (p2);Die Mission ist erledigt! Wir haben gerade den Vererbungsmodus des Prototyps in JavaScript abgeschlossen!
Abbildung 7
Zusammenfassen
Ich hoffe, dieser Artikel hilft Ihnen dabei, das Geheimnis von JavaScript -Prototyp -Konzepten aufzudecken. Was ich zuerst sah, war, wie der Prototyp ein Objekt ermöglichte, Funktionen von anderen Objekten zu erben, und dann sah, wie man den neuen Operator und den Konstruktor kombiniert, um das Objekt zu erstellen. Was hier erwähnt wird, ist nur der erste Schritt, um die Leistung und Flexibilität des Objektprototyps freizuschalten. Dieser Artikel ermutigt Sie, neue Informationen zu Prototypen und JavaScript -Sprachen für sich selbst zu entdecken und zu lernen.
Bitte fahren Sie auch vorsichtig. Sie werden nie wissen, welche (fehlerhafte) Technologie diese Fahrzeuge auf der Straße von ihren Prototypen erben werden.
Original -Link: Skript -Junkie -Übersetzung: Bole Online - Emje