Vererbung und PrototypenketteWenn es um Vererbung geht, hat JavaScript nur eine Konstruktion: das Objekt. Jedes Instanzobjekt verfügt über eine private Eigenschaft (Proto genannt), die auf das Prototypobjekt seines Konstruktors verweist. Das Prototypobjekt hat auch sein eigenes Prototypobjekt (Proto), Schicht für Schicht, bis das Prototypobjekt eines Objekts null ist. Per Definition hat null keinen Prototyp und dient als letztes Glied in dieser Prototypenkette. Fast alle Objekte in JavaScript sind Instanzen von Object, das sich am oberen Ende der Prototypenkette befindet. Geerbte EigenschaftenJavaScript-Objekte sind dynamische „Säcke“ mit Eigenschaften (die sich auf ihre eigenen Eigenschaften beziehen). JavaScript-Objekte haben einen Link zu einem Prototypobjekt. Wenn Sie versuchen, auf eine Eigenschaft eines Objekts zuzugreifen, wird nicht nur im Objekt selbst, sondern auch im Prototyp des Objekts und im Prototyp des Prototyps des Objekts usw. gesucht, bis eine Eigenschaft mit passendem Namen gefunden wird oder das Ende der Prototypenkette erreicht wird. Codebeispiel Funktion fn() { dies.a = 1; dies.b = 2; } const o = neue fn(); fn.prototype.b = 3; fn.prototype.c = 4; Konsole.log(oa); console.log(ob); konsole.log(oc); konsole.log(od); // 1 // 2 // 4 // undefiniert
Schauen Sie sich den Ausdruck des o-Konstruktors an { ein: 1 b: 2 __proto__: b: 3 c: 4 Konstruktor: ƒ fn() __proto__: Konstruktor: ƒ Object() hatEigeneEigenschaft: ƒ hatEigeneEigenschaft() istPrototypVon: ƒ istPrototypVon() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() Wert von: ƒ Wert von () __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() bekomme __proto__: ƒ __proto__() setze __proto__: ƒ __proto__() } Geerbte MethodenJavaScript hat keine „Methoden“, wie andere klassenbasierte Sprachen sie definieren. In JavaScript kann einem Objekt jede beliebige Funktion als Eigenschaft des Objekts hinzugefügt werden. Die Funktionsvererbung unterscheidet sich nicht von der Vererbung anderer Eigenschaften, einschließlich der oben erwähnten „Eigenschaftsverschattung“ (die dem Überschreiben von Methoden in anderen Sprachen entspricht). Wenn eine geerbte Funktion aufgerufen wird, bezieht sich dies auf das aktuelle geerbte Objekt und nicht auf das Prototypobjekt, in dem sich die geerbte Funktion befindet. var o = { eine: 2, m: Funktion () { gib dies zurück.a + 1; }, }; console.log(om()); // 3 // Beim Aufruf von om bezieht sich „this“ auf o. var p = Objekt.create(o); // p ist ein Objekt, das von o erbt pa = 4; // Erstelle ps eigenes Attribut „a“ konsole.log(pm()); // 5 // Beim Aufruf von pm zeigt 'this' auf p // Und weil p die m-Funktion von o erbt, // ist daher 'this.a', also pa, ps eigenes Attribut 'a' Verwenden von Prototypen in JavaScriptIn JavaScript dürfen Funktionen Eigenschaften haben. Alle Funktionen haben eine spezielle Eigenschaft namens Prototyp. Standardmäßig ist es das Prototypobjekt von Object Funktion tuEtwas() {} Konsole.log(mache etwas.Prototyp); // Es hat nichts damit zu tun, wie die Funktion deklariert wird. //Funktionen in JavaScript haben immer eine Standard-Prototyp-Eigenschaft. var tuEtwas = Funktion () {}; Konsole.log(mache etwas.Prototyp); Im in der Konsole angezeigten JavaScript-Codeblock sehen wir einen Standardeigenschaftsprototyp für die Funktion doSomething. Nach dem Ausführen dieses Codes sollte die Konsole ähnliche Ergebnisse wie die folgenden anzeigen: { Konstruktor: ƒ doSomething(), __proto__: { Konstruktor: ƒ Object(), hatEigeneEigenschaft: ƒ hatEigeneEigenschaft(), istPrototypeOf: ƒ istPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), Wert von: ƒ Wert von () } } Wir können dem Prototypobjekt der Funktion doSomething wie folgt neue Eigenschaften hinzufügen: Funktion tuEtwas() {} doSomething.prototype.foo = "Leiste"; Konsole.log(mache etwas.Prototyp); Sie können die Ergebnisse nach dem Ausführen wie folgt sehen: { foo: "Leiste", Konstruktor: ƒ doSomething(), __proto__: { Konstruktor: ƒ Object(), hatEigeneEigenschaft: ƒ hatEigeneEigenschaft(), istPrototypeOf: ƒ istPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), Wert von: ƒ Wert von () } } Jetzt können wir den neuen Operator verwenden, um eine Instanz von doSomething basierend auf diesem Prototypobjekt zu erstellen. Code: Funktion tuEtwas() {} doSomething.prototype.foo = "bar"; // füge dem Prototyp eine Eigenschaft hinzu var doSomeInstancing = neues doSomething(); doSomeInstancing.prop = "irgendein Wert"; // füge dem Objekt eine Eigenschaft hinzu console.log(macheEinigeInstanz); Das Ergebnis der Ausführung ähnelt der folgenden Anweisung. { Requisite: „ein gewisser Wert“, __proto__: { foo: "Leiste", Konstruktor: ƒ doSomething(), __proto__: { Konstruktor: ƒ Object(), hatEigeneEigenschaft: ƒ hatEigeneEigenschaft(), istPrototypeOf: ƒ istPrototypeOf(), propertyIsEnumerable: ƒ propertyIsEnumerable(), toLocaleString: ƒ toLocaleString(), toString: ƒ toString(), Wert von: ƒ Wert von () } } } Wir können sehen, dass prop die Eigenschaft von doSomeInstancing selbst ist und proto in doSomeInstancing doSomething.prototype ist. Wir drucken die Eigenschaften innen console.log("doSomeInstancing.prop: " + doSomeInstancing.prop); console.log("doSomeInstancing.foo: " + doSomeInstancing.foo); console.log("macheSomething.prop: " + macheSomething.prop); console.log("macheEtwas.foo: " + macheEtwas.foo); console.log("macheSomething.prototype.prop: " + macheSomething.prototype.prop); console.log("macheSomething.prototype.foo: " + macheSomething.prototype.foo); Die Ergebnisse sind wie folgt: // Die eigenen Eigenschaften von doSomeInstancing geben den Wert direkt zurück doSomeInstancing.prop: some value // Es ist keine Eigenschaft von doSomeInstancing selbst. Überprüfen Sie das Prototypobjekt und stellen Sie fest, dass es diese Eigenschaft gibt, die direkt den Wert doSomeInstancing.foo: bar zurückgibt. // Es ist weder eine Eigenschaft der Funktion selbst, noch eine Eigenschaft des Prototypobjekts. Wenn wir Schicht für Schicht nach oben suchen und schließlich feststellen, dass der Prototyp null ist, bedeutet dies, dass es keine solche Eigenschaft gibt. Daher geben wir undefined zurück. doSomething.prop: nicht definiert doSomething.foo: nicht definiert doSomething.prototype.prop: nicht definiert // Finde das Prototypobjekt von doSomething und es hat die Eigenschaft foo, also gib direkt den Wert doSomething.prototype.foo zurück: bar LeistungDas Nachschlagen von Eigenschaften in der Prototypenkette ist zeitaufwändig und wirkt sich negativ auf die Leistung aus, was in leistungskritischen Situationen wichtig ist. Darüber hinaus durchlaufen Versuche, auf nicht vorhandene Eigenschaften zuzugreifen, die gesamte Prototypenkette. Beim Durchlaufen der Eigenschaften eines Objekts wird jede aufzählbare Eigenschaft in der Prototypkette aufgezählt. Um zu überprüfen, ob ein Objekt eine Eigenschaft hat, die es selbst definiert, und nicht eine Eigenschaft in seiner Prototypenkette, müssen Sie die Methode hasOwnProperty verwenden, die alle Objekte von Object.prototype erben. Hier ist ein konkretes Beispiel zur Veranschaulichung: console.log(doSomeInstancing.hasOwnProperty("prop")); // WAHR console.log(doSomeInstancing.hasOwnProperty("bar")); // FALSCH console.log(doSomeInstancing.hasOwnProperty("foo")); // FALSCH console.log(doSomeInstancing.__proto__.hasOwnProperty("foo")); // WAHR hasOwnProperty ist die einzige Methode in JavaScript, die sich mit Eigenschaften befasst und nicht die Prototypenkette durchläuft. Eine weitere solche Methode: Object.keys() Hinweis: Durch die Überprüfung, ob eine Eigenschaft nicht definiert ist, können Sie nicht feststellen, ob sie existiert. Die Eigenschaft ist möglicherweise bereits vorhanden, ihr Wert ist jedoch zufällig auf „undefiniert“ eingestellt. Anhang: Die Prototypenkette ist die Hauptmethode zur Erzielung von VererbungLassen Sie uns zunächst über Vererbung sprechen. Viele OO-Sprachen unterstützen zwei Vererbungsmethoden: Schnittstellenvererbung und Implementierungsvererbung. |- Schnittstellenvererbung: nur Methodensignaturen erben |- Implementierungsvererbung: Vererbung tatsächlicher Methoden Da Funktionen keine Signaturen haben, kann die Schnittstellenvererbung in ECMAScript nicht implementiert werden. Es wird nur die Implementierungsvererbung unterstützt, und die Implementierungsvererbung wird hauptsächlich über die Prototypenkette erreicht. Die Grundidee der Prototypkette: Verwenden Sie Prototypen, um einen Referenztyp die Eigenschaften und Methoden eines anderen Referenztyps erben zu lassen. Jeder Konstruktor hat ein Prototypobjekt, das einen Zeiger auf den Konstruktor (Konstruktor) enthält, und das Instanzobjekt enthält einen internen Zeiger auf das Prototypobjekt (__proto__). Wenn Sie das Prototypobjekt einer Instanz eines anderen Typs gleichsetzen, enthält das Prototypobjekt einen Zeiger auf einen anderen Prototyp (__proto__), und der andere Prototyp enthält auch einen Zeiger auf eine andere Konstruktorfunktion (Konstruktor). Wenn ein anderer Prototyp eine Instanz eines anderen Typs ist, … bildet dies eine Kette von Instanzen und Prototypen. Die Grundidee der Prototypkette (Diagramm): ZusammenfassenDies ist das Ende dieses Artikels über Js-Vererbung und Prototypenkette. Weitere relevante Inhalte zu Js-Vererbung und Prototypenkette finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Das kürzeste JS, um festzustellen, ob es sich um IE6 handelt (IE-Schreibmethode)
1. Überprüfen Sie sql_mode wählen Sie @@sql_mode ...
Besonderer Hinweis: Es wird nur die Swoole-Erweit...
Inhaltsverzeichnis Ursachen der MySQL-Tabellenfra...
Beispiel: Wir verwenden den Python-Code loop_hell...
Da das, was ich zuvor geschrieben habe, nicht det...
In diesem Artikelbeispiel wird der spezifische Ja...
Inhaltsverzeichnis Vorwort 1. Aktuelle Uhrzeit er...
Aktivieren Sie den Fernzugriff Aktivieren Sie die...
Inhaltsverzeichnis Vorwort Webpack-Deb-Server Sta...
Vorwort Docker kann Umgebungsvariablen für Contai...
Das Definieren des Datenfeldtyps in MySQL ist für...
Shtml und asp sind ähnlich. In Dateien mit dem Nam...
ausstellen Design Passwortstärke-Analyse Das Pass...
Ergebnis: Der Hauptteil besteht darin, die Codelo...
Bei der Datenbankoperation ist der Umgang mit Dat...