1. Was ist ein Prototyp?Prototypen bilden die Grundlage der Vererbung in Javascript, und die Vererbung in JavaScript basiert auf der Prototypenvererbung. 1.1 FunktionsprototypobjektWenn wir in JavaScript eine Funktion A erstellen (dh eine Funktion deklarieren), erstellt der Browser ein Objekt B im Speicher, und jede Funktion verfügt standardmäßig über einen Eigenschaftenprototyp, der auf dieses Objekt verweist (dh der Wert der Prototypeigenschaft ist dieses Objekt). Dieses Objekt B ist das Prototypobjekt der Funktion A oder einfach der Prototyp der Funktion. Standardmäßig verfügt das Prototypobjekt B über einen Eigenschaftskonstruktor, der auf die Funktion A verweist (d. h. der Wert der Konstruktoreigenschaft ist Funktion A). Sehen Sie sich den folgenden Code an: <Text> <Skripttyp="text/javascript"> /* Wenn Sie eine Funktion deklarieren, verfügt sie standardmäßig über eine Eigenschaft namens „Prototyp“. Und der Browser erstellt automatisch ein Objekt gemäß bestimmten Regeln. Dieses Objekt ist das Prototypobjekt dieser Funktion, und die Prototypeigenschaft verweist auf dieses Prototypobjekt. Dieses Prototypobjekt hat eine Eigenschaft namens Konstruktor, die diese Funktion ausführt Hinweis: Standardmäßig hat das Prototypobjekt nur ein Attribut: Konstruktor. Die anderen werden von Object geerbt und berücksichtigen Sie sie daher vorerst nicht. */ Funktion Person () { } </Skript> </body> Das folgende Diagramm beschreibt, was nach der Deklaration einer Funktion passiert: 1.2 Erstellen von Objekten mit KonstruktorenWenn eine Funktion als Konstruktor verwendet wird (theoretisch kann jede Funktion als Konstruktor verwendet werden) und ein Objekt mit „new“ erstellt wird, verfügt das Objekt standardmäßig über eine unsichtbare Eigenschaft, die auf das Prototypobjekt des Konstruktors verweist. Diese unsichtbare Eigenschaft wird normalerweise durch [[Prototyp]] dargestellt, aber auf diese Eigenschaft kann nicht direkt zugegriffen werden. Sehen Sie sich den folgenden Code an: <Text> <Skripttyp="text/javascript"> Funktion Person () { } /* Wenn ein Objekt mit einem Konstruktor erstellt wird, wird dem Objekt automatisch eine unsichtbare Eigenschaft [[Prototyp]] hinzugefügt, die auf das Prototypobjekt des Konstruktors verweist. */ var p1 = neue Person(); </Skript> </body> Beachten Sie das folgende Diagramm: veranschaulichen: 1. Wie aus der obigen Abbildung ersichtlich ist, wird zwar der Personenkonstruktor zum Erstellen des p1-Objekts verwendet, aber nachdem das Objekt erstellt wurde, hat das p1-Objekt tatsächlich nichts mit dem Personenkonstruktor zu tun. Die Eigenschaft [[ prototype ]] des p1-Objekts zeigt auf das Prototypobjekt des Personenkonstruktors. 2. Wenn Sie mit „new Person()“ mehrere Objekte erstellen, verweisen alle Objekte gleichzeitig auf das Prototypobjekt der Konstruktorfunktion „Person“. 3. Wir können diesem Prototypobjekt manuell Eigenschaften und Methoden hinzufügen, dann teilen sich die Objekte p1, p2, p3... die im Prototyp hinzugefügten Eigenschaften und Methoden. 4. Wenn wir auf einen Attributnamen in p1 zugreifen und dieser im p1-Objekt gefunden wird, wird er direkt zurückgegeben. Wenn das Objekt nicht im p1-Objekt gefunden wird, wird direkt im Prototypobjekt gesucht, auf das die Eigenschaft [[prototype]] des p1-Objekts zeigt, und es wird zurückgegeben, wenn es gefunden wird. (Wenn es im Prototyp nicht gefunden wird, suchen Sie weiter nach dem Prototyp des Prototyps – der Prototypenkette. Ich werde später darüber sprechen.) 5. Wenn ein Attributname über das p1-Objekt hinzugefügt wird, ist der Attributname im Prototyp für das p1-Objekt abgeschirmt. Mit anderen Worten: Es gibt keine Möglichkeit, auf den Eigenschaftsnamen des Prototyps in p1 zuzugreifen. 6. Das p1-Objekt kann den Wert des Attributnamens im Prototyp nur lesen, kann den Wert des Attributnamens im Prototyp jedoch nicht ändern. p1.name = "Eigenschaft"; ändert den Wert im Prototyp nicht, fügt dem p1-Objekt jedoch einen Eigenschaftsnamen hinzu. Sehen Sie sich den folgenden Code an: <Text> <Skripttyp="text/javascript"> Funktion Person () { } // Sie können Person.prototype verwenden, um direkt auf das Prototypobjekt zuzugreifen. // Fügen Sie dem Prototypobjekt der Person-Funktion einen Eigenschaftsnamen hinzu, dessen Wert „Zhang San“ lautet. Person.Prototyp.Name = "Zhang San"; Person.Prototyp.Alter = 20; var p1 = neue Person(); /* Greifen Sie auf die Eigenschaft „Name“ des Objekts p1 zu. Obwohl wir die Eigenschaft „Name“ nicht explizit zum Objekt p1 hinzugefügt haben, verfügt der Prototyp, auf den die Eigenschaft [[prototype]] von p1 verweist, über die Eigenschaft „Name“, sodass hier auf die Eigenschaft „Name“ zugegriffen werden kann. Es lohnt sich. Hinweis: Derzeit kann das Namensattribut nicht über das p1-Objekt gelöscht werden, da nur in p1 gelöschte Objekte gelöscht werden können. */ alarm(p1.name); // Zhang San var p2 = neue Person(); alert(p2.name); // Zhang San hat beides im Prototyp gefunden, also sind sie gleich. alarm(p1.name === p2.name); // wahr // Da der Wert im Prototyp nicht geändert werden kann, fügt diese Methode p1 direkt einen neuen Attributnamen hinzu. Anschließend kann in p1 nicht mehr auf die Attribute im // Prototyp zugegriffen werden. p1.name = "Li Si"; alarm("p1: " + p1.name); // Da in p2 kein Namensattribut vorhanden ist, greift p2 trotzdem auf das Attribut im Prototyp zu. alert("p2:" + p2.name); // Zhang San</script> </body> 2. Verschiedene Eigenschaften und Methoden im Zusammenhang mit Prototypen2.1 Prototyp-Eigenschaft Der Prototyp existiert in der Konstruktorfunktion (tatsächlich existiert er in jeder Funktion, aber der Prototyp ist uns egal, wenn es sich nicht um eine Konstruktorfunktion handelt) und er verweist auf das Prototypobjekt dieser Konstruktorfunktion. Siehe vorheriges Diagramm. 2.2 Konstruktor-EigenschaftDie Konstruktor-Eigenschaft existiert im Prototyp-Objekt und zeigt auf den Konstruktor Sehen Sie sich den folgenden Code an: <Skripttyp="text/javascript"> Funktion Person () { } alarm(Person.prototype.constructor === Person); // wahr var p1 = neue Person(); //Verwenden Sie den Operator „instanceof“, um den Typ eines Objekts zu bestimmen. //typeof wird im Allgemeinen verwendet, um einfache Typen und Funktionen zu erhalten. Referenztypen verwenden im Allgemeinen „instanceof“, da „typeof“ für Referenztypen immer ein Objekt zurückgibt. alert(p1 Instanz von Person); // wahr </Skript> Bei Bedarf können wir mit der Eigenschaft Person.prototype ein neues Objekt als Prototypobjekt von Person angeben. Allerdings gibt es derzeit ein Problem: Die Konstruktoreigenschaft des neuen Objekts verweist nicht mehr auf den Person-Konstruktor. Sehen Sie sich den folgenden Code an: <Skripttyp="text/javascript"> Funktion Person () { } //Weisen Sie dem Prototyp der Person direkt Objektliterale zu. Dann zeigt die Konstruktor-Eigenschaft dieses Objekts nicht mehr auf die Person-Funktion Person.prototype = { Name: „Name“, Alter:20 }; var p1 = neue Person(); alert(p1.name); // Zhiling alert(p1 Instanz von Person); // wahr Alarm (Person.Prototyp.Konstruktor === Person); //falsch //Wenn Ihnen der Konstruktor wichtig ist, sollten Sie Person.prototype eine Zeile wie diese hinzufügen: /* Person.Prototyp = { Konstruktor: Person //Leitet den Konstruktor zur Funktion „Person“ um. } */ </Skript> 2.3 __proto__-Attribut (Hinweis: Auf jeder Seite stehen zwei Unterstriche)Nach dem Erstellen eines neuen Objekts mit einem Konstruktor gibt es im Objekt standardmäßig eine nicht zugängliche Eigenschaft [[prototype]]. Diese Eigenschaft zeigt auf das Prototypobjekt des Konstruktors. Allerdings bieten auch einige Browser Zugriff auf diese Eigenschaft [[Prototyp]] (Chrome und Firefox. Internet Explorer unterstützt dies nicht). Zugriffsmethode: p1.__proto__ Entwickler sollten jedoch versuchen, nicht auf diese Weise darauf zuzugreifen, da durch unachtsame Vorgehensweise die Prototyp-Vererbungskette dieses Objekts geändert werden kann. <Skripttyp="text/javascript"> Funktion Person () { } //Weisen Sie dem Prototyp der Person direkt Objektliterale zu. Dann zeigt die Konstruktor-Eigenschaft dieses Objekts nicht mehr auf die Person-Funktion Person.prototype = { Konstruktor: Person, Name: „Name“, Alter:20 }; var p1 = neue Person(); Alarm (p1.__proto__ === Person.prototype); //wahr </Skript> 2.4 hasOwnProperty()-MethodeWie wir alle wissen, kann beim Zugriff auf die Eigenschaften eines Objekts diese Eigenschaft vom Objekt selbst oder vom Prototyp stammen, auf den die Eigenschaft [[Prototyp]] dieses Objekts verweist. Wie ermitteln Sie also die Quelle dieses Objekts? Mit der Methode hasOwnProperty kann ermittelt werden, ob eine Eigenschaft vom Objekt selbst stammt. <Skripttyp="text/javascript"> Funktion Person () { } Person.prototype.name = "Person"; var p1 = neue Person(); p1.sex = "weiblich"; //Das Geschlechtsattribut wird direkt zum p1-Attribut hinzugefügt, daher ist es wahr alert("Die Eigenschaft „sex“ gehört zum Objekt selbst: " + p1.hasOwnProperty("sex")); // Das Namensattribut wird im Prototyp hinzugefügt und ist daher falsch alert("Die Eigenschaft „Name“ gehört zum Objekt selbst: " + p1.hasOwnProperty("name")); // Das Altersattribut existiert nicht, daher ist es auch falsch alert("Die Alterseigenschaft existiert im Objekt selbst: " + p1.hasOwnProperty("age")); </Skript> Daher kann mit der Methode hasOwnProperty bestimmt werden, ob dem Objekt selbst ein Objekt hinzugefügt wird, es kann jedoch nicht bestimmt werden, ob es im Prototyp vorhanden ist, da die Möglichkeit besteht, dass die Eigenschaft nicht vorhanden ist. Das heißt, Eigenschaften im Prototyp und nicht vorhandene Eigenschaften geben „false“ zurück. Wie kann ermittelt werden, ob eine Eigenschaft im Prototyp vorhanden ist? 2,5 Zoll OperatorMit dem In-Operator wird ermittelt, ob in diesem Objekt eine Eigenschaft vorhanden ist. Bei der Suche nach dieser Eigenschaft suchen wir allerdings im Objekt selbst. Kann das Objekt nicht gefunden werden, suchen wir im Prototyp. Mit anderen Worten: Solange die Eigenschaft entweder im Objekt oder im Prototyp vorhanden ist, wird „true“ zurückgegeben. <Skripttyp="text/javascript"> Funktion Person () { } Person.prototype.name = "Person"; var p1 = neue Person(); p1.sex = "weiblich"; alert("sex" in p1); // Das Objekt selbst wird hinzugefügt, also true alert("name" in p1); //Existiert im Prototyp, also wahr alert("age" in p1); //Existiert nicht im Objekt oder Prototyp, also false </Skript> Zurück zur vorherigen Frage: Wenn wir feststellen, ob eine Eigenschaft im Prototyp vorhanden ist: Wenn eine Eigenschaft zwar vorhanden ist, jedoch nicht im Objekt selbst, muss sie im Prototyp vorhanden sein. <Skripttyp="text/javascript"> Funktion Person () { } Person.prototype.name = "Person"; var p1 = neue Person(); p1.sex = "weiblich"; //Definieren Sie eine Funktion, um den Speicherort der Prototypfunktion zu bestimmen propertyLocation(obj, prop){ wenn(!(Eigenschaft in Objekt)){ alert(prop + "Eigenschaft existiert nicht"); }sonst wenn(obj.hasOwnProperty(prop)){ alert(prop + "Eigenschaft existiert im Objekt"); }anders { alert(prop + "Objekt existiert im Prototyp"); } } propertyLocation(p1, "Alter"); Eigenschaftsstandort (p1, "Name"); propertyLocation(p1, "Geschlecht"); </Skript 3. Kombinieren des Prototypmodells und des Konstruktormodells zum Erstellen von Objekten3.1 Mängel bei der Erstellung von Prototyp-ModellobjektenAlle Eigenschaften im Prototyp werden geteilt. Das heißt, wenn Objekte, die mit derselben Konstruktorfunktion erstellt wurden, auf Eigenschaften im Prototyp zugreifen, greifen alle auf dasselbe Objekt zu. Wenn ein Objekt die Eigenschaften des Prototyps ändert, wird dies in allen Objekten widergespiegelt. Bei der tatsächlichen Verwendung sind die Eigenschaften der einzelnen Objekte jedoch im Allgemeinen unterschiedlich. Zhang San heißt Zhang San und Li Si heißt Li Si. ** Diese Freigabefunktion eignet sich jedoch sehr gut für Methoden (Eigenschaftswerte sind Eigenschaften von Funktionen). **Alle Methoden zum Teilen von Objekten sind optimal. Diese Funktion ist nativ in C# und Java. 3.2 Mängel bei der Objekterstellung mithilfe des KonstruktormodellsJedes Objekt verfügt über eine eigene, eindeutige Kopie der im Konstruktor hinzugefügten Eigenschaften und Methoden und diese werden nicht gemeinsam genutzt. Diese Funktion ist für Eigenschaften geeignet, aber nicht für Methoden. Da für alle Objekte eine Kopie ihrer Methoden ausreichen sollte, ist es nicht erforderlich, für jede Person eine Kopie zu haben, was zu Speicherverschwendung und schlechter Leistung führen würde. <Skripttyp="text/javascript"> Funktion Person() { dieser.name = "Li Si"; dieses.Alter = 20; dies.essen = funktion() { alert("Ich bin mit dem Essen fertig"); } } var p1 = neue Person(); var p2 = neue Person(); //Jedes Objekt hat unterschiedliche Methoden alert(p1.eat === p2.eat); //false </Skript> Zur Lösung des Problems können Sie die folgende Methode verwenden: <Skripttyp="text/javascript"> Funktion Person() { dieser.name = "Li Si"; dieses.Alter = 20; dies.essen = essen; } Funktion essen() { alert("Ich bin mit dem Essen fertig"); } var p1 = neue Person(); var p2 = neue Person(); //Da dem eat-Attribut die gleiche Funktion zugewiesen ist, ist es wahr Alarm(p1.essen === p2.essen); //wahr </Skript> Die obige Lösung weist jedoch einen schwerwiegenden Fehler auf: eine schlechte Kapselung. Einer der Zwecke der objektorientierten Programmierung besteht darin, Code zu kapseln. Zu diesem Zeitpunkt muss der Code aus Leistungsgründen aus dem Objekt extrahiert werden, was ein unmenschliches Design ist. 3.3 Verwenden Sie den Kombinationsmodus, um die beiden oben genannten Mängel zu behebenDas Prototypmuster eignet sich zum Einkapseln von Methoden, und das Konstruktormuster eignet sich zum Einkapseln von Eigenschaften. Durch die Kombination der Vorteile beider Muster entsteht das kombinierte Muster. <Skripttyp="text/javascript"> //Eigenschaften in der Konstruktorfunktion einkapseln Person(name, age) { dieser.name = Name; dieses.Alter = Alter; } // Kapsele die Methode im Prototypobjekt Person.prototype.eat = function (food) { Alarm (dieser.Name + "Lebensmittel" + Essen); } Person.prototype.play = Funktion (Spielname) { alert(this.name + "Spielname" + Spielname); } var p1 = neue Person("Li Si", 20); var p2 = neue Person("Person", 30); p1.eat("Apfel"); p2.eat("Banane"); p1.play("Spiel"); p2.play("Feng Jie"); </Skript> 4. Der dynamische Prototypmodus erstellt Objekte Auch der oben erwähnte Kombinationsmodus ist nicht perfekt, und es gibt eine Sache, die sich nicht perfekt anfühlt. Das separate Schreiben von Konstruktor und Prototyp ist für viele Menschen immer unangenehm. Wir sollten einen Weg finden, Konstruktor und Prototyp zusammen zu kapseln, sodass ein dynamischer Prototypmodus entsteht. Der dynamische Prototypmodus kapselt alle Eigenschaften und Methoden im Konstruktor und initialisiert den Prototyp nur bei Bedarf im Konstruktor, wobei die Vorteile der Verwendung sowohl des Konstruktors als auch des Prototyps erhalten bleiben. Sehen Sie sich den folgenden Code an: <Skripttyp="text/javascript"> //Konstruktor interne Kapselungseigenschaften Funktion Person(name, age) { //Jedes Objekt fügt seine eigenen Eigenschaften hinzu this.name = name; dieses.Alter = Alter; /* Bestimmen Sie, ob das Attribut this.eat eine Funktion ist. Wenn es keine Funktion ist, beweist dies, dass das Objekt zum ersten Mal erstellt wird. Fügen Sie diese Funktion dann dem Prototyp hinzu. Wenn es sich um eine Funktion handelt, bedeutet dies, dass diese Methode bereits im Prototyp vorhanden ist und nicht hinzugefügt werden muss. perfekt! Löst die Leistungs- und Codekapselungsprobleme perfekt. */ wenn(Typ von diesem.eat !== "Funktion"){ Person.prototype.eat = Funktion () { Alarm (dieser Name + "Essen"); } } } var p1 = neue Person("Person", 40); p1.essen(); </Skript> Dies ist das Ende dieses Artikels zum gründlichen Verständnis des Prototypobjekts in JavaScript. Weitere Informationen zum Verständnis des JS-Prototypobjekts finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
>>: Schritte zum Übertragen von Dateien und Ordnern zwischen zwei Linux-Servern
Ich habe gerade am frühen Morgen die Installation...
Dieser Artikel veranschaulicht anhand von Beispie...
Vorwort Ich glaube, die meisten Leute haben MySQL...
Da die Plattform weiter wächst, ist die Forschung...
0. Als ich dieses Dokument erstellte, war es unge...
1. Zweck Schreiben Sie lokal eine Flask-Anwendung...
Tutorial zur npm-Installation: 1. Laden Sie das N...
In der Front-End-Entwicklung gibt es viele Möglic...
Inhaltsverzeichnis 1. DateTimePicker Datumsauswah...
Werfen wir einen Blick auf ufw (Uncomplicated Fir...
Verwenden Sie den Linux-Befehl chmod , um zu steu...
In diesem Artikelbeispiel wird der spezifische Co...
Bei der Entwicklung für Mobilgeräte tritt häufig ...
In diesem Artikel wird der spezifische Code von j...
Nach Funktion sortierenNN: Gibt an, welche frühere...