Ausführliche Erläuterung der verschiedenen Methoden sowie der Vor- und Nachteile der JavaScript-Vererbung

Ausführliche Erläuterung der verschiedenen Methoden sowie der Vor- und Nachteile der JavaScript-Vererbung

1. Vererbung der Prototypkette

Funktion Übergeordnet () {
    dieser.name = "kevin";
}

Parent.prototype.getName = Funktion () {
    konsole.log(dieser.name);
}

Funktion Kind () {

}

Kind.Prototyp = neues Elternteil();

var Kind1 = neues Kind();

console.log(child1.getName()) // kevin

Frage:

1. Die Eigenschaften von Referenztypen werden von allen Instanzen gemeinsam genutzt. Beispiel:

Funktion Übergeordnet () {
    diese.namen = ['kevin', 'daisy'];
}

Funktion Kind () {

}

Kind.Prototyp = neues Elternteil();

var Kind1 = neues Kind();

child1.names.push('ja');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var Kind2 = neues Kind();

console.log(child2.names); // ["kevin", "daisy", "yayu"]

2. Beim Erstellen einer Child-Instanz können Sie keine Parameter an Parent übergeben

2. Konstruktoren ausleihen (klassische Vererbung)

Funktion Übergeordnet () {
    diese.namen = ['kevin', 'daisy'];
}

Funktion Kind () {
    Übergeordneter Aufruf (dies);
}

var Kind1 = neues Kind();

child1.names.push('ja');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var Kind2 = neues Kind();

console.log(child2.names); // ["kevin", "daisy"]

Vorteil:

  • 1. Verhindert, dass Eigenschaften von Referenztypen von allen Instanzen gemeinsam genutzt werden
  • 2. Sie können Parameter von Child an Parent übergeben

Zum Beispiel:

Funktion Übergeordnet (Name) {
    dieser.name = Name;
}

Funktion Kind (Name) {
    Übergeordnet.call(dieser, Name);
}

var Kind1 = neues Kind('Kevin');

console.log(Kind1.Name); // Kevin

var Kind2 = neues Kind('Daisy');

console.log(Kind2.Name); // Daisy

Mangel:

  • Methoden werden im Konstruktor definiert und jedes Mal, wenn eine Instanz erstellt wird, wird die Methode erneut erstellt.

3. Kombinationsvererbung

Prototypische Vererbung und klassische Vererbung arbeiten zusammen.

Funktion Übergeordnet (Name) {
    dieser.name = Name;
    diese.farben = ['rot', 'blau', 'grün'];
}

Parent.prototype.getName = Funktion () {
    console.log(dieser.Name)
}

Funktion Kind (Name, Alter) {

    Übergeordnet.call(dieser, Name);

    dieses.Alter = Alter;

}

Kind.Prototyp = neues Elternteil();

var Kind1 = neues Kind('Kevin', '18');

Kind1.Farben.push('schwarz');

console.log(Kind1.Name); // Kevin
console.log(Kind1.Alter); // 18
console.log(child1.colors); // ["rot", "blau", "grün", "schwarz"]

var Kind2 = neues Kind('Daisy', '20');

console.log(Kind2.Name); // Daisy
console.log(Kind2.Alter); // 20
console.log(child2.colors); // ["rot", "blau", "grün"]

Vorteile: Es kombiniert die Vorteile der Prototypkettenvererbung und der Konstruktorfunktion und ist der am häufigsten verwendete Vererbungsmodus in JavaScript.

4. Prototypenvererbung

Funktion erstelleObj(o) {
    Funktion F(){}
    F.Prototyp = o;
    gib neues F() zurück;
}


Es handelt sich um eine simulierte Implementierung von ES5 Object.create , die das übergebene Objekt als Prototyp des erstellten Objekts verwendet.

Nachteile: Eigenschaftswerte, die Referenztypen enthalten, teilen sich immer die entsprechenden Werte, genau wie bei der Vererbung in der Prototypkette.

var Person = {
    Name: 'kevin',
    Freunde: ['Daisy', 'Kelly']
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = "Person1";
console.log(person2.name); // kevin

person1.firends.push('taylor');
console.log(person2.freunde); // ["daisy", "kelly", "taylor"]

Hinweis: Wenn der Wert von person1.name geändert wird, ändert sich der Wert von person2.name nicht. Dies liegt nicht daran, dass person1 und person2 unabhängige name haben, sondern daran, dass person1.name = 'person1' name zu person1 hinzufügt, anstatt den Namenswert im Prototyp zu ändern.

5. Parasitäre Vererbung

Erstellen Sie eine Funktion, die nur zum Kapseln des Vererbungsprozesses dient, das Objekt intern in irgendeiner Form erweitert und schließlich das Objekt zurückgibt.

Funktion createObj (o) {
    var clone = Objekt.erstellen(o);
    Klon.sayName = Funktion () {
        console.log('hallo');
    }
    Klon zurückgeben;
}

Nachteile: Wie beim geliehenen Konstruktormuster wird bei jeder Erstellung eines Objekts eine Methode erstellt.

6. Parasitäre kombinatorische Vererbung

Der Einfachheit halber wiederholen wir hier den kombinierten Vererbungscode:

Funktion Übergeordnet (Name) {
    dieser.name = Name;
    diese.farben = ['rot', 'blau', 'grün'];
}

Parent.prototype.getName = Funktion () {
    console.log(dieser.Name)
}

Funktion Kind (Name, Alter) {
    Übergeordnet.call(dieser, Name);
    dieses.Alter = Alter;
}

Kind.Prototyp = neues Elternteil();

var Kind1 = neues Kind('Kevin', '18');

console.log(Kind1)

Der größte Nachteil der zusammengesetzten Vererbung besteht darin, dass der übergeordnete Konstruktor zweimal aufgerufen wird.

Einmal beim Festlegen des Prototyps einer Untertypinstanz:

Kind.Prototyp = neues Elternteil();

Einmal beim Erstellen einer Instanz des Untertyps:

var Kind1 = neues Kind('Kevin', '18');

Erinnern Sie sich an die Simulationsimplementierung von new. Tatsächlich werden wir in diesem Satz Folgendes ausführen:

Übergeordnet.call(dieser, Name);

Hier rufen wir den Parent-Konstruktor erneut auf.

Wenn wir also in diesem Beispiel das Objekt child1 drucken, werden wir feststellen, dass Child.prototype als auch child1 eine Eigenschaft namens colors mit dem Wert ['red', 'blue', 'green']。

Wie können wir also nach Spitzenleistungen streben und diesmal wiederholte Anrufe vermeiden?

Was wäre, wenn wir nicht Child.prototype = new Parent() verwenden, sondern Child.prototype indirekt auf Parent.prototype zugreifen lassen?

Sehen Sie, wie es umgesetzt wird:

Funktion Übergeordnet (Name) {
    dieser.name = Name;
    diese.farben = ['rot', 'blau', 'grün'];
}

Parent.prototype.getName = Funktion () {
    console.log(dieser.Name)
}

Funktion Kind (Name, Alter) {
    Übergeordnet.call(dieser, Name);
    dieses.Alter = Alter;
}

// Drei wichtige Schritte var F = function () {};

F.Prototyp = Übergeordneter Prototyp;

Kind.Prototyp = neues F();


var Kind1 = neues Kind('Kevin', '18');

Konsole.log(Kind1);

Abschließend kapseln wir diese Vererbungsmethode:

Funktionsobjekt (o) {
    Funktion F() {}
    F.Prototyp = o;
    gib neues F() zurück;
}

Funktion Prototyp (Kind, Elternteil) {
    var Prototyp = Objekt(übergeordneter.Prototyp);
    Prototyp.Konstruktor = Kind;
    child.prototype = Prototyp;
}

// Wenn wir verwenden:
Prototyp (Kind, Elternteil);

Zitat aus dem Lob der parasitären kombinatorischen Vererbung in „Advanced JavaScript Programming“:

Die Effizienz dieses Ansatzes besteht darin, dass der Parent Konstruktor nur einmal aufgerufen wird und somit die Erstellung unnötiger, redundanter Eigenschaften in Parent.prototype vermieden wird. Gleichzeitig bleibt die Prototypenkette unverändert; daher können instanceof und isPrototypeOf weiterhin normal verwendet werden. Entwickler sind im Allgemeinen davon überzeugt, dass die parasitäre Kompositionsvererbung das ideale Vererbungsparadigma für Referenztypen ist.

Damit ist dieser Artikel mit einer ausführlichen Erklärung der verschiedenen Vererbungsarten in JavaScript und ihrer Vor- und Nachteile abgeschlossen. Weitere Informationen zu den verschiedenen Vererbungsarten in JavaScript und ihren Vor- und Nachteilen finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der Js-Klassenkonstruktion und Vererbungsfälle
  • Ein Artikel bringt Ihnen die Vererbung von JS-Funktionen bei
  • Wie gut wissen Sie über die Vererbung in JavaScript?
  • Unterschiede zwischen ES6-Vererbung und ES5-Vererbung in js
  • Ein kurzer Vortrag über die parasitäre Kompositionsvererbung in JavaScript
  • Erläuterung der objektorientierten Klassenvererbung in JavaScript

<<:  Docker Nginx-Container und Tomcat-Container zur Realisierung von Lastausgleich und dynamischen und statischen Trennungsvorgängen

>>:  Detaillierte Erklärung der Zeichensätze und Validierungsregeln in MySQL

Artikel empfehlen

mysqldump-Parameter, die Sie möglicherweise nicht kennen

Im vorherigen Artikel wurde erwähnt, dass die in ...

Eine einfache Möglichkeit, das Passwort in MySQL 5.7 zu ändern

Dies ist ein offizieller Screenshot. Nach der Ins...

So verwenden Sie CSS-Overflow: Hidden (Überlauf ausblenden und Floats löschen)

Überlauf ausblenden Damit ist gemeint, dass Text-...

Detaillierte Erklärung der grep- und egrep-Befehle in Linux

Vertreter / egrep Syntax: grep [-cinvABC] 'wo...

Detaillierte Erläuterung des einzeiligen Funktionscodes des Datumstyps in MySQL

Einzeilige Funktionen vom Datumstyp in MySQL: CUR...

Analyse des Unterschieds zwischen fettgedrucktem <b> und <strong>

Wir alle Webmaster wissen, dass es bei der Optimi...

Vue verwendet Echart, um Beschriftungen und Farben anzupassen

In diesem Artikelbeispiel wird der spezifische Co...

Tomcat-Quellcodeanalyse und -Verarbeitung

Inhaltsverzeichnis Vorwort 1. Endpunkt 2. Verbind...

Detaillierte Erläuterung der sechs gängigen Einschränkungstypen in MySQL

Inhaltsverzeichnis Vorwort 1.nichtnull 2. einziga...

So konfigurieren Sie den Tomcat-Server für Eclipse und IDEA

Tomcat-Serverkonfiguration Jeder, der das Web ken...

So lösen Sie das Problem des verstümmelten DOS-Fensters in MySQL

Das Problem mit dem verstümmelten Code ist folgen...

Äußerst detaillierte Freigabe der MySQL-Nutzungsspezifikation

In letzter Zeit waren viele datenbankbezogene Vor...