VorwortVererbung ist ein unverzichtbarer Bestandteil der JS-Welt und wird als einer der drei Berge von JS bezeichnet. Mit dieser Methode können wir den vorherigen Entwicklungscode besser wiederverwenden, den Entwicklungszyklus verkürzen und die Entwicklungseffizienz verbessern. Vor ES6 wurden Klassen in JS durch Konstruktoren simuliert und es gab keine echten Klassen. Obwohl die Klasse in ES6 ein Syntaxzucker ist, konnten Klassen in dieser Zeit direkt als Funktionen verwendet werden. Nach ES6 können Klassen nicht mehr als Funktionen verwendet werden. Bevor wir über Vererbung sprechen, müssen wir zunächst klarstellen, dass es in einer Klasse zwei Arten von Attributen gibt: Instanzattribute und öffentliche Attribute. Alle im Folgenden besprochenen Vererbungsmethoden drehen sich um diese beiden Punkte. Funktion Tier(Name) { // Attribut der Instanz this.name = name; } // Öffentliche Eigenschaften Animal.prototype.eat = function() { // zu erledigen ... } Wie vermeidet man, Konstruktoren vor ES6 direkt als Funktionen aufzurufen? ES5-Lösung: Funktion Tier() { // Bei direktem Aufruf ohne Verwendung von new wird eine Ausnahme ausgelöst, wenn (!(diese Instanz von Animal)) { // Das Prinzip von new. Wenn new verwendet wird, handelt es sich um eine Instanz von Animal, dann ist diese Instanz von Animal wahr throw new Error("Den Konstruktor nicht direkt aufrufen"); } } ES6 und spätere Lösungen: Funktion Tier() { // Wenn new verwendet wird, zeigt new.target auf sich selbst, andernfalls ist es undefiniert. Es kann jedoch nicht beim Erben verwendet werden, da das ursprüngliche es5 beim Erben von Eigenschaften einer Instanz Animal.call(this) if (!new.target) { verwendet. throw new Error("Den Konstruktor nicht direkt aufrufen"); } } Beide der oben genannten Lösungen können gelöst werden, indem sie direkt als Funktionen aufgerufen werden. Wenn Sie die Konsole direkt aufrufen, wird ein Fehler gemeldet: Nicht abgefangener Fehler: Rufen Sie den Konstruktor nicht direkt auf Als nächstes werfen wir einen Blick auf die Vererbungsmethoden in JS Vererbung von PrototypkettenDie Vererbung in der Prototypkette ist eine der gebräuchlichsten Vererbungsmethoden. Zwischen dem beteiligten Konstruktor, Prototyp und der Instanz besteht eine bestimmte Beziehung, d. h. jeder Konstruktor hat ein Prototypobjekt, das Prototypobjekt enthält einen Zeiger auf den Konstruktor und die Instanz enthält einen Zeiger auf das Prototypobjekt. Funktion Person(Name) { dieser.name = Name; this.permission = ["Benutzer", "Gehalt", "Urlaub"]; } Person.prototype.say = Funktion () { console.log(`${this.name} hat gesprochen`); }; Funktion Personal(Alter) { dieses.Alter = Alter; } Mitarbeiter.Prototyp = neue Person("Zhang San"); const zs = neues Personal(12); console.log(zs.name); // Zhang Sanzs.say(); // Zhang San hat gesprochen An diesem Punkt entspricht der Code den Erwartungen. Erstellen Sie als Nächstes eine Instanz und ändern Sie den Namen und die Berechtigung. const zs = neues Personal(12); const zs2 = neues Personal(18); zs.permission.pop() zs.name = "Li Si"; Konsole.log(zs.name); console.log(zs2.name); console.log(zs.permission); console.log(zs2.permission); Die Ausgaben der ersten beiden sind: Li Si und Zhang San, während die Ausgaben der letzten beiden gleich sind, beide ["Benutzer", "Gehalt"]. Warum passiert das? zs2.name durchsucht weiterhin die Prototypenkette, sodass die ersten beiden Ausgaben Li Si und Zhang San sind Durch die Ausgabe von true über console.log(zs.__proto__ === zs2.__proto__); können wir erkennen, dass die beiden Instanzen dasselbe Prototypobjekt Person verwenden und ihren Speicherplatz gemeinsam nutzen. Wenn sich eine ändert, ändert sich auch die andere entsprechend. Aus dem oben Gesagten geht hervor, dass die Vererbung von Prototypketten einige Nachteile hat KonstruktorvererbungKonstruktoren verwenden normalerweise call und apply, um die Vererbung abzuschließen Funktion Person(Name) { dieser.name = Name; this.permission = ["Benutzer", "Gehalt", "Urlaub"]; } Person.prototype.say = Funktion () { console.log(`${this.name} hat gesprochen`); }; Funktion Mitarbeiter(Name, Alter) { Person.call(dieser, Name); dieses.Alter = Alter; } Mitarbeiter.prototype.eat = Funktion () { console.log('Lass uns essen~~~~'); } const zs = new Staff("Zahl", 12); konsole.log(zs); Der obige Code gibt die Konsole aus: Es ist ersichtlich, dass es nicht nur die Eigenschaften und Methoden von Staff hat, sondern auch die Eigenschaften von Person erbt, da Person.call (this, name) bei jeder Instanziierung aufgerufen wird, wodurch das Problem der Vererbung der Prototypkette gelöst werden kann. Rufen Sie zu diesem Zeitpunkt die Methode für den Personenprototyp auf zs.sagen() Zu diesem Zeitpunkt meldet die Konsole einen Fehler: Uncaught TypeError: zs.say ist keine Funktion Kombinationsvererbung (Kombination aus Prototypkettenvererbung und Konstruktorvererbung)Sowohl die Prototypkettenvererbung als auch die Konstruktorvererbung haben ihre eigenen Probleme und Vorteile. Durch die Kombination der beiden Vererbungsmethoden entsteht eine zusammengesetzte Vererbung. Funktion Person(Name) { dieser.name = Name; this.permission = ["Benutzer", "Gehalt", "Urlaub"]; } Person.prototype.say = Funktion () { console.log(`${this.name} hat gesprochen`); }; Funktion Mitarbeiter(Name, Alter) { // Zweite Ausführung von Person Person.call(dieser, Name); dieses.Alter = Alter; } Mitarbeiter.prototype.eat = Funktion () { console.log("Lass uns essen~~~~"); }; // Erste Ausführung von Person Mitarbeiter.Prototyp = neue Person(); // Wenn Sie den Staff-Konstruktor nicht zurück auf Staff verweisen, verweist die Staff-Instanz zs.constructor auf Person Staff.prototype.constructor = Mitarbeiter; const zs = new Staff("Zahl", 12); const ls = neuer Stab("Li Si", 12); zs.permission.pop(); console.log(zs.permission); console.log(ls.permission); zs.sagen(); ls.sagen(); Vorerst ist die Konsolenausgabe normal und die beiden oben genannten Vererbungsmängel sind behoben, es treten jedoch zwei neue Probleme auf:
Parasitäre VererbungIndem Object.create verwendet wird, um eine oberflächliche Kopie des Zielobjekts zu erhalten, und dann einige Methoden hinzugefügt werden, um eine Verschmutzung der Basisklasse zu vermeiden, wird hauptsächlich das zweite Problem der zusammengesetzten Vererbung gelöst. Ersetzen Sie hauptsächlich die folgenden beiden Codezeilen Mitarbeiter.Prototyp = neue Person(); Staff.prototype.constructor = Mitarbeiter; Ersetzen durch: Mitarbeiter.Prototyp = Objekt.Erstellen(Person.Prototyp, { Konstruktor: { // Wenn Sie den Staff-Konstruktor nicht zurück auf Staff verweisen, verweist die Staff-Instanz zs.constructor auf Person Wert: Mitarbeiter, }, }); Kombinatorische parasitäre VererbungBisher besteht noch das Problem der zweimaligen Instanziierung von Personen, das nicht gelöst wurde. Die folgende kombinierte parasitäre Vererbung kann das obige Problem perfekt lösen. Dies ist auch die beste Vererbungsmethode unter allen Vererbungsmethoden vor ES6. Der vollständige Code lautet wie folgt: Funktion Person(Name) { dieser.name = Name; this.permission = ["Benutzer", "Gehalt", "Urlaub"]; } Person.prototype.say = Funktion () { console.log(`${this.name} hat gesprochen`); }; Funktion Mitarbeiter(Name, Alter) { Person.call(dieser, Name); dieses.Alter = Alter; } Mitarbeiter.Prototyp = Objekt.Erstellen(Person.Prototyp, { Konstruktor: { // Wenn Sie den Staff-Konstruktor nicht zurück auf Staff verweisen, verweist die Staff-Instanz zs.constructor auf Person Wert: Mitarbeiter, }, }); Mitarbeiter.prototype.eat = Funktion () { console.log("Lass uns essen~~~~"); }; Tatsächlich gibt es beim Erben mehr Möglichkeiten, Staff.prototype zu ändern, auf das verwiesen wird, als nur die oben genannten. Es gibt auch einige andere Methoden
Mitarbeiter.prototype.__proto__ = Person.prototype Es gibt ein Kompatibilitätsproblem mit prototype.__proto__. Es kann nicht von selbst gefunden werden. Es sucht weiter nach oben durch die Prototypenkette. Zu diesem Zeitpunkt teilen sich Animal und Tiger nicht mehr dieselbe Adresse und beeinflussen sich nicht gegenseitig.
Objekt.setPrototypeOf(Mitarbeiter.Prototyp, Person.Prototyp) es6-Syntax, es besteht Kompatibilität, das Prinzip ist die Methode prototype.__proto__ erweitertNach ES6 können Sie Extends zur Vererbung verwenden, was auch die am häufigsten verwendete Methode in der aktuellen Entwicklung ist. Obwohl die Browserunterstützung nicht ideal ist, sind dies mit der Verbesserung der heutigen Technik keine Gründe mehr, die Verwendung einzuschränken. Klasse Person { Konstruktor(Name) { dieser.name = Name; this.permission = ["Benutzer", "Gehalt", "Urlaub"]; } sagen() { console.log(`${this.name} hat gesprochen`); } } Klasse Staff erweitert Person { Konstruktor(Name, Alter) { super(name); dieses.Alter = Alter; } essen() { console.log("Lass uns essen~~~~"); } } Tatsächlich wird nach der Kompilierung der ES6-Vererbung durch Babel auch die kombinierte parasitäre Vererbung übernommen, sodass wir uns auf die Beherrschung des Vererbungsprinzips konzentrieren müssen. ZusammenfassenDamit ist dieser Artikel über die sechs Vererbungsmethoden und ihre Vor- und Nachteile in JS abgeschlossen. Weitere Informationen zu JS-Vererbungsmethoden und ihren Vor- und Nachteilen 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:
|
<<: Lösen Sie das Problem der Ausführung von „Hello World“ nach der Docker-Installation
>>: So stellen Sie mit Navicat Premium eine Remoteverbindung zur MySQL-Datenbank her
Verwenden von NULL in Vergleichsoperatoren mysql&...
Vorwort: Manchmal wird die mit MySQL verbundene S...
Durch Hinzufügen des Schlüsselworts extra_hosts i...
Vor ein paar Tagen habe ich einen von Yu Bo getei...
Inhaltsverzeichnis Zusammenfassung Gesamtprozess ...
Konzepteinführung: Wir wissen, dass das Redo-Log ...
axios installieren und Kommunikation implementier...
In diesem System steht das #-Zeichen für den Root...
Der spezifische Code lautet wie folgt: <!DOCTY...
Machen Sie sich anhand von Beispielen mit der Bede...
Wenn Ihre Webanwendung nur auf einer Maschine läu...
Vue+Openlayer verwendet „modify“, um Elemente zu ...
Verwenden Sie reines CSS, um die Hintergrundfarbe...
Dieses Problem ist mir beim Erstellen der Anmelde...
1. Seite der virtuellen Maschine 1. Suchen Sie di...