Die Erklärung der JavaScript -Erbschaft wurde vereinbart, aber es wurde verzögert. Kommen Sie ohne weiteres auf den Punkt.
Da Sie die Vererbung verstehen möchten, beweist dies, dass Sie bereits ein gewisses Verständnis von JavaScript-Objektorientierungen haben. Wenn Sie nichts verstehen, können Sie sich auf die grundlegende Erläuterung von objektorientiertem JS, dem Werksmodus, dem Konstruktormodus, dem Prototypmodus, dem gemischten Modus, dem dynamischen Prototypmodus beziehen.
Prototypkette
Der einfachste Weg, die Vererbung in JavaScript zu implementieren, besteht darin, eine Prototypkette zu verwenden und den Prototyp des untergeordneten Typs auf eine Instanz des übergeordneten Typs zu richten, dh "Subtyp.Prototype = neuer übergeordneter Typ ();". Die Implementierungsmethode lautet wie folgt:
// Erstellen Sie eine Konstruktorfunktion SuperType () {this.name = ['Wuyuchang', 'Jack', 'Tim']; this.property = true;} // Methode superType.prototype.getSuerPerValue = function () {return this.property;} // Erstellen Sie eine Konstruktor -Funktion subtyp () {this.test = ['H1', 'H2', 'H3', 'H4']; this.subProperty = false;} // Schlüsselschritte zur Implementierung der Vererbung verweist der Prototyp des Subtyps auf eine Instanz des übergeordneten Typs Subtyp.Prototype = new SuperType (); // Fügen Sie hier eine Methode zum untergeordneten Typ hinzu. Es muss nach der Implementierung der Erbschaft erfolgen, sonst wird der Zeiger auf eine Instanz des übergeordneten Typs hingewiesen, und die Methode ist leer. Subtyp.Prototype.getSubValue = function () {return this.subProperty;}/* Das folgende Beispiel ist ein Testcode -Beispiel*/var instance1 = new Subtyp (); Instance1.name.push ('Wir); instance1.test.push (' H5 '); // Truealert (Instance1.getSubValue ()); // falsealert (Instance1.Name); // Wuyuchang, Jack, Tim, Wycalert (Instance1.test); // H1, H2, H3, H4, H5var Instance2 = neuer Subtyp (); alert (Instance2.Name); // Wuyuchang, Jack, Tim, Wycalert (Instance2.Test); // H1, H2, H3, H4Sie können sehen, dass der obige Code eine einfache Vererbung ist, die über die Prototyp -Kette implementiert wird, aber es gibt immer noch einige Probleme im Testcode -Beispiel. I believe that after reading my blog post "Basic Explanation of Object-Oriented JS, Factory Mode, Constructor Mode, Prototype Mode, Mixed Mode, Dynamic Prototype Mode", I must know that the first problem with the prototype chain code is that the prototype of the subtype is an instance of the parent type, that is, the attributes of the parent type contained in the prototype of the subtype, which causes the prototype attributes that reference the type Der Wert wird von allen Fällen geteilt . Die Instanz1.Name.push ('Wyc'); des oben genannten Code kann die Existenz dieses Problems beweisen. Das zweite Problem mit der Prototypkette ist, dass beim Erstellen einer Instanz eines Subtyps Parameter nicht an den Supertyp -Konstruktor übergeben werden können . Daher verwenden wir in der tatsächlichen Entwicklung nur selten Prototypketten allein.
Konstruktor ausleihen
Um zwei Probleme in der Prototypkette zu lösen, begannen Entwickler, eine Technik namens Kreditkonstruktoren zu verwenden, um Probleme in der Prototypkette zu lösen. Die Implementierungsidee dieser Technologie ist ebenfalls recht einfach. Sie müssen nur den Konstruktor des übergeordneten Typs im Konstruktor des Subtyps aufrufen. Vergessen Sie nicht, dass Funktionen nur Objekte sind, die Code in einer bestimmten Umgebung ausführen. Daher können Konstruktoren über die Methode apply () oder call () ausgeführt werden . Der Code ist wie folgt:
// Erstellen Sie eine Konstruktorfunktion SuperType (Name) {this.name = name; this.color = ['pink', 'gelb']; this.property = true; this.TestFun = function () {alert ('http://tools.vevb.com/'); }} // Methode superType.prototype.getSuerPerValue = function () {return this.property;} // Erstellen einer Konstruktorfunktion Subtyp (Name) {SuperType.call (this, name) erstellen; this.test = ['H1', 'H2', 'H3', 'H4']; this.subProperty = false;} // Fügen Sie hier eine Methode zum Subtyp hinzu. Stellen Sie sicher, dass Sie die Vererbung implementieren. Andernfalls wird der Zeiger auf eine Instanz des übergeordneten Typs hingewiesen, und die Methode ist leer. 'Nick']); Instance1.Name.push ('Hallo'); Instance1.test.push ('H5'); Instance1.color.push ('Blue'); Instance1.TestFun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, Hallo // alarm (Instanz1.getSuerPerValue ()); // Fehleralarm (Instance1.test); // H1, H2, H3, H4, H5 Alert (Instance1.getSubValue ()); // False Alert (Instance1.Color); // Pink, Yellow, Bluevar Instance2 = neuer Subtyp ('Wyc'); Instance2.TestFun (); // http://tools.vevb.com/alert(instance2.Name); // wyc // alert (instance2.getSuerPerValue ()); // Fehleralarm (Instance2.test); // H1, H2, H3, H4alert (Instance2.getSubValue ()); // falsealert (Instance2.Color); // Pink, gelbSie können sehen, dass im obigen Code der Konstruktor des Subtyp -Subtyps im obigen Code die Vererbung des Attributs realisiert wird, indem der übergeordnete Typ "SuperType.call (dieser, Name) aufgerufen wird;". Sie können auch Parameter an den übergeordneten Typ übergeben, wenn der Subtyp erstellt wird, aber es kommt ein neues Problem. Sie können sehen, dass ich eine Methode im Konstruktor des übergeordneten Typs definiert habe: TestFun und eine Methode im Prototyp des übergeordneten Typs: getuperValue. Nach dem Instanziieren des Subtyps ist es jedoch immer noch unmöglich, die im Prototyp des übergeordnete Typs definierte Methode zu nennen , und kann nur die Methode des Konstruktors im übergeordneten Typ aufrufen: TestFun. Dies entspricht nur dem Konstruktormodus beim Erstellen von Objekten, so dass die Funktion keine Wiederverwendbarkeit hat. Unter Berücksichtigung dieser Probleme werden die Techniken der Kreditkonstruktoren nur selten allein eingesetzt.
Kombinationsvererbung (Prototyp -Kette + Ausleihenkonstruktor)
Wie der Name schon sagt, ist die Kombinationsvererbung ein Muster, das sich aus den Vorteilen der Kombination der Verwendung von Prototypketten und Kreditkonstruktoren zusammensetzt. Die Implementierung ist auch sehr einfach. Da es sich um eine Kombination handelt, kombiniert es natürlich die Vorteile beider Parteien, nämlich die Prototyp -Kette -Vererbungsmethode, und die Konstruktor -Attribute . Der spezifische Code wird wie folgt implementiert:
// Erstellen Sie eine Konstruktorfunktion SuperType (Name) {this.name = name; this.color = ['pink', 'gelb']; this.property = true; this.TestFun = function () {alert ('http://tools.vevb.com/'); }} // Methode superType.prototype.getSuerPerValue = function () {return this.property;} // Erstellen einer Konstruktorfunktion Subtyp (Name) {SuperType.call (this, name) erstellen; this.test = ['H1', 'H2', 'H3', 'H4']; this.subProperty = false;} subtyp.Prototype = new SuperType (); // Fügen Sie hier eine Methode zum Subtyp hinzu. Es muss sein, nachdem die Vererbung implementiert wurde, andernfalls wird der Zeiger auf eine Instanz des übergeordneten Typs hingewiesen, und die Methode ist leer. 'Nick']); Instance1.Name.push ('Hallo'); Instance1.test.push ('H5'); Instance1.color.push ('Blue'); Instance1.TestFun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, HelloArt (Instance1.getSuerPerValue ()); // Truealert (Instance1.test); // H1, H2, H3, H4, H5 Alert (Instance1.getSubValue ()); // False Alert (Instance1.Color); // Pink, Yellow, Bluevar Instance2 = neuer Subtyp ('Wyc'); Instance2.TestFun (); // http://tools.vevb.com/alert(instance2.Name); // WYC Alert (Instance2.getSuerPerValue ()); // Truealert (Instance2.Test); // H1, H2, H3, H4alert (Instance2.getSubValue ()); // falsealert (Instance2.Color); // Pink, gelbDer obige Code erbt die Eigenschaften des übergeordneten Typs über SuperType.call (this, Name); und erbt die Methoden des übergeordneten Typs durch Subtyp.Prototype = new SuperType ();. Der obige Code löst bequem die Probleme, die von Prototypketten und Kreditkonstruktoren auftreten, und ist zur am häufigsten verwendeten Methode zur Instanzvererbung in JavaScript. Der gemischte Modus ist jedoch nicht ohne Mängel. Es ist ersichtlich, dass im obigen Code die Attribute des übergeordneten Typs tatsächlich geerbt wurden, wenn die Methode erbt. Der Referenztyp wird zu diesem Zeitpunkt jedoch geteilt. Daher wird der Konstruktor des übergeordneten Typs im Konstruktor des untergeordneten Typs nach dem Subtyp aufgerufen, wodurch die Attribute des übergeordneten Typs erbt, um die ererbten Attribute im Prototyp zu überschreiben. Es ist offensichtlich nicht notwendig, den Konstruktor zweimal anzurufen, aber gibt es eine Möglichkeit, ihn zu lösen? Schauen Sie sich bei der Lösung dieses Problems zunächst die folgenden zwei Modi an.
Prototyp -Vererbung
Die Implementierungsmethode des Prototypenvereritzs unterscheidet sich von der der gewöhnlichen Vererbung. Der Prototyp -Vererbung verwendet keinen Konstruktor im strengen Sinne, sondern verwendet den Prototyp, um neue Objekte basierend auf vorhandenen Objekten zu erstellen, und es müssen keine benutzerdefinierten Typen erstellt werden. Der spezifische Code lautet wie folgt:
Funktionsobjekt (o) {Funktion f () {} f.prototype = o; Neue f () zurückgeben;}Codebeispiel:
/* Prototypenerbschaft*/Funktion Objekt (o) {Funktion f () {} f.prototype = o; Neue f ();} var person = {name: 'wuyuchang', Freunde: ['wyc', 'nicholas', 'tim']} var AnotherPerson = Object (Person); otherperson.name = 'Greg'; otherperson.friends.push ('bob'); var otherperson2 = Object (Person); otherPerson2.name = 'Jack'; otherPerson2.friends.push ('rose'); alert (Person.friends); // WYC, Nicholas, Tim, Bob, RoseParasitäres Vererbung
/* Parasitärer Vererbung*/Funktion createanother (ursprünglich) {var klone = Objekt (original); clone.sayhi = function () {alert ('hi'); } return clone;}Beispiel der Nutzung:
/* Prototypenerbschaft*/Funktion Objekt (o) {Funktion f () {} f.prototype = o; Neue f () zurückgeben; clone.sayhi = function () {alert ('hi'); } return clone;} var person = {name: 'wuyuchang', Freunde: ['wyc', 'nicholas', 'rose']} var AnotherPerson = createanother (Person); otherperson.sayhi ();Parasitäre Kombinationserbranz
Ich erwähnte früher die Nachteile der Kombinationsmuster -Implementierung der Vererbung in JavaScript. Lassen Sie uns nun seine Mängel lösen. Die Implementierungsidee besteht darin, Attribute für Konstruktoren zu erben, und die Vererbungsmethode der gemischten Form der Prototypkette muss den Konstruktor des übergeordneten Typs beim Erben der Methode nicht instanziieren. Der Code ist wie folgt:
Funktionsobjekt (o) {Funktion f () {} f.prototype = o; Neue f ();}/* parasitische Kombination Inheritance*/Funktion InheritPrototype (subtyp, SuperType) {var prototype = Object (SuperType.Prototyp); Prototyp.Constructor = Subtyp; subtyp.Prototype = prototyp;}Bei der Verwendung müssen Sie nur die Codezeile "Subtype.Prototype = new SuperType () ersetzen; Im Kombinationsmodus mit InheritPrototype (Subtyp, SuperType);. Die Effizienz des parasitären kombinatorischen Vererbung spiegelt sich darin wider, dass es den übergeordneten Konstruktor nur einmal aufruft und die Erstellung unnötiger oder redundanter Eigenschaften vermeidet. Gleichzeitig kann die Prototyp -Kette unverändert bleiben, sodass InstanceOF und isprototypeof () auch normal verwendet werden können. Dies ist derzeit auch die idealste Vererbungsmethode und verwandelt sich derzeit in dieses Modell. (Yui verwendet auch diesen Modus.)
Dieser Blog -Beitrag bezieht sich auf "JavaScript Advanced Programming 3rd Edition". Der Code wird neu geschrieben und spezifischer und kommentiert, um es jedem zu erleichtern, es zu verstehen. Wenn Sie einzigartige Einblicke in das JS -Erbe haben, seien Sie nicht geizig. Antwort auf deine Meinungen als Referenz!