Prototypverkettung in JavaScript

8

Ich lese ein Buch mit dem Namen JavaScript-Muster, aber es gibt einen Teil, bei dem der Typ verwirrend ist.

Der Typ führte das Buch tatsächlich zum Klass-Design-Muster, wo er es Stück für Stück entwickelte. Er stellt zuerst das Problem vor:

%Vor%

Er sagt:

"Das gibt Ihnen kurze und schnelle Kettennachschlagewerke, weil alle Objekte den gleichen Prototyp haben. Aber das ist auch ein ZUVERLÄSSIG, denn wenn ein Kind oder ein Enkelkind Irgendwo in der Vererbungskette MODIFIZIERT der Prototyp, es betrifft alle Eltern und Großeltern. "

Allerdings habe ich tatsächlich versucht, den Prototyp say () in Child zu ändern und hatte keinen Einfluss auf Parent und tatsächlich zeigte Child noch auf Parent und ignorierte seinen eigenen Prototyp mit dem gleichen Namen, was sinnvoll ist, da er auf a zeigt unterschiedliche Speicherposition. Wie kann der Typ so etwas sagen? Unten beweist mein Punkt:

%Vor%

Es ist unmöglich, dass ein Kind oder ein Enkelkind den Prototyp verändert!

Das führt zu meinem zweiten Punkt. Er sagt, die Lösung für das Problem der Möglichkeit, Elternprototypen die Vererbungskette (die ich nicht reproduzieren kann) zu verändern, besteht darin, die direkte Verbindung zwischen dem Prototyp des Elternteils und des Kindes zu brechen und gleichzeitig von der Prototypkette zu profitieren. Er bietet folgendes als Lösung an:

%Vor%

Das Problem ist, dass es dieselben genauen Werte wie das andere Muster ausgibt:

%Vor%

Es macht keinen Sinn, dass eine leere Funktion irgendwie eine Verbindung unterbricht. Tatsächlich zeigt das Kind auf F und F zeigt wiederum auf den Prototyp des Elternteils. Sie zeigen also immer noch auf die gleiche Speicherposition. Dies wird oben demonstriert, wo es die gleichen genauen Werte wie das erste Beispiel ausgibt. Ich habe keine Ahnung, was dieser Autor zu demonstrieren versucht und warum er Behauptungen macht, die für mich nicht gelten und die ich nicht reproduzieren kann.

Danke für die Antwort.

    
JohnMerlino 08.11.2010, 21:27
quelle

4 Antworten

8

Für Ihren ersten Punkt:

Was dieser Typ zu sagen versucht, ist, dass sich die Methoden für Kind und Eltern ändern, wenn Sie den Prototyp nach ändern, den Sie Instanzen erstellt haben.

Zum Beispiel:

%Vor%

Das Gleiche passiert, wenn Sie den Konstruktor des Kindes ändern (der mit dem Elternteil geteilt wird).

%Vor%

Und über Ihren zweiten Punkt:

%Vor%

Die neue Funktion übernimmt den Konstruktor des Elternteils vom Kind, da er nicht mehr auf dasselbe Objekt verweist, sondern jetzt auf einen Prototyp einer neu erstellten Funktion zeigt, die nichts mit dem Elternteil zu tun hat. Sie erstellen also eine lokale Kopie des Konstruktors des übergeordneten Elements und erstellen dann eine neue Instanz der Kopie, die alle Konstruktormethoden und Eigenschaften zurückgibt. Durch das Ändern des Konstruktors des untergeordneten Elements wirkt sich dies nicht auf das übergeordnete Element aus.

%Vor%     
Harmen 08.11.2010, 21:38
quelle
2

Die Tatsache, dass Sie das Prototyp-Objekt ändern können, indem Sie auf einen anderen Prototyp zeigen, ist normales JavaScript-Verhalten. Primitive JavaScript-Werte sind unveränderbar, Objekte und Arrays jedoch nicht. Ich werde es mit einem einfachen Beispiel erklären:

%Vor%

Arrays haben das gleiche Verhalten:

%Vor%

Sehen wir uns die Zeichenketten und boolesche Werte (primitive Datentypen) an:

%Vor%

Ich hatte das gleiche Problem, aber ich habe es behoben. Schau, ich habe deinen Code kommentiert, einige Hinweise darin sollten dir helfen:

%Vor%

Das Problem besteht hier darin, dass Sie anstelle des Kopierens und Änderns des Parent.prototype die neue Child.prototype.say-Methode erstellen und direkt danach das gesamte Child.prototype-Objekt durch Parent.prototype-Zuweisung umschreiben. Ändern Sie einfach ihre Reihenfolge und es sollte gut funktionieren.

    
orustam 05.06.2011 09:20
quelle
1

Wenn Sie den Prototyp ändern, nachdem Sie ihn geerbt haben, sehen Sie, dass er auch den Prototyp für das übergeordnete Element ändert:

%Vor%

Wenn Sie die modifizierte Version der Funktion inherit verwenden, bleiben die Prototypen Child und Parent getrennt.

    
Guffa 08.11.2010 21:35
quelle
0

Erstellen einer Funktion

%Vor%

Erstellen eines Objekts

%Vor%

Verwenden von instanceOf

%Vor%

Denken Sie daran:

  • Object.prototype.constructor = Object (class/function/object)
  • Function.prototype.__proto__ = Object.prototype
  • Konstruktoren haben ihre eigene {Prototyp} -Kette, die vollständig von der Prototypkette von Objekten getrennt ist, die sie initialisieren.
  • Jede benutzerdefinierte Funktion in JavaScript erhält automatisch eine Prototypeigenschaft, die wiederum eine Konstruktoreigenschaft besitzt, die auf die Funktion zurückgreift.
  • Jede benutzerdefinierte Funktion in JavaScript kann als Konstruktor aufgerufen werden, indem dem Aufruf eine neue Funktion vorangestellt wird. Dadurch wird der Funktion ein neues "this" -Objekt übergeben, und die Eigenschaft {Prototype} wird auf die prototype -Eigenschaft der Funktion gesetzt.

Beispiel:

%Vor%

console.log(myobject instanceof MyConstructor); // prints "false". Why? See below.

  • instanceof always Überprüft die Prototypkette von myobject.
  • myobject.__proto__ zeigt auf das alte MyConstructor.prototype-Objekt.
  • Old MyConstructor.prototype zeigt __proto__ auf Object.prototype.
  • Irgendwo in der Prototypkette von myobject ist MyConstructor also nicht gekommen. Daher falsch.

console.log(myobject.constructor == MyConstructor) // prints "true"

  • myobject.__proto__ zeigt auf altes MyConstructor.prototype Objekt.
  • Old MyConstructor.prototype.constructor zeigt auf MyConstructor .
  • Daher zeigt myobject.constructor auf MyConstructor .

console.log(myobject instanceof Object); //prints "true"

  • myobject.__proto__ zeigt auf altes MyConstructor.prototype Objekt.
  • alt MyConstructor.prototype.__proto__ = Object.prototype
  • daher myObject-Prototyp-Kette hat Objekt in seiner Liste

Um die Vererbung zu implementieren

Um die klassische Vererbung zu implementieren, müssen Sie die Prototypketten nutzen. Da Eigenschaften und Methoden im __proto__ eines Objekts gesucht werden, müssen Sie den Prototyp seiner Klasse ändern (Sie können __proto__ nicht ändern), wenn Sie möchten, dass er von einem anderen Objekt erbt.

%Vor%

Zeile 1-3

%Vor%

Zeile 4-7

%Vor%

Zeile 8

%Vor%

Zeile 9

%Vor%

Jetzt, wenn Sie die folgende Zeile ausführen

%Vor%

dann verweist tommy.__proto__ auf Dog.prototype . Da "hasHair" nicht in Dog.prototype gefunden wurde, finden wir es in Dog.prototype.__proto__ , was sich auf Animal.prototype bezieht, was es hat. Also, tommy.hasHair wird wahr sein.

{}

  • {} creates an object.
  • {}.__proto__ === Object.prototype
  • {}.constructor === Object
Vipul 29.03.2015 20:30
quelle