Heim > Artikel > Web-Frontend > Objektorientierte JavaScript-Programmierung (Vererbungsimplementierung)
Viele OO-Sprachen unterstützen zwei Vererbungsmethoden: Schnittstellenvererbung und Implementierungsvererbung. Die Schnittstellenvererbung erbt nur Methodensignaturen, während die Implementierungsvererbung die tatsächlichen Methoden erbt. Wie bereits erwähnt, ist eine Schnittstellenvererbung in ECMAScript nicht möglich, da Funktionen keine Signaturen haben. ECMAScript unterstützt nur die Implementierungsvererbung, und seine Implementierungsvererbung basiert hauptsächlich auf der Prototypenkette. Hier erklären wir hauptsächlich die Vererbung von Prototypenketten, geliehene Konstruktoren, kombinierte Vererbung, Prototypenvererbung, parasitäre Vererbung, parasitäre Kombinationsvererbung usw.
1. Prototypenkette
ECMAScript beschreibt das Konzept der Prototypenkette und verwendet die Prototypenkette als Hauptmethode zur Implementierung der Vererbung. Die Grundidee besteht darin, mithilfe von Prototypen einem Referenztyp die Eigenschaften und Methoden eines anderen Referenztyps erben zu lassen. Sehen wir uns kurz die Beziehung zwischen Konstruktoren, Prototypen und Instanzen an: Jeder Konstruktor verfügt über ein Prototypobjekt, das Prototypobjekt enthält einen Zeiger auf den Konstruktor und die Instanz enthält einen internen Zeiger auf das Prototypobjekt. Was passiert also, wenn wir das Prototypobjekt einer Instanz eines anderen Typs gleichsetzen? Offensichtlich enthält das Prototypobjekt zu diesem Zeitpunkt einen Zeiger auf einen anderen Prototyp, und dementsprechend enthält der andere Prototyp auch einen Zeiger auf einen anderen Konstruktor. Wenn ein anderer Prototyp eine Instanz eines anderen Typs ist, gilt die obige Beziehung weiterhin, und so wird Schicht für Schicht eine Kette von Instanzen und Prototypen gebildet. Dies ist das Grundkonzept der sogenannten Prototypenkette.
function Person(){ this.name=”defaultName”; } Person.property.doAction=function(){ alert(“talk”); } function Student(){ this.age=5; } Student.property=new Person(); Student.property.doSome=function(){ alert(“ homework”); }
Obwohl die Prototypenkette sehr leistungsfähig ist und zur Implementierung der Vererbung verwendet werden kann, weist sie auch einige Probleme auf. Das Hauptproblem ergibt sich aus Prototypen, die Referenztypwerte enthalten. Sie erinnern sich vielleicht noch daran, dass wir zuvor eingeführt haben, dass Prototypeigenschaften, die Referenztypwerte enthalten, von allen Instanzen gemeinsam genutzt werden. Aus diesem Grund sollten Eigenschaften im Konstruktor und nicht im Prototypobjekt definiert werden. Wenn die Vererbung durch Prototypen implementiert wird, wird der Prototyp tatsächlich zu einer Instanz eines anderen Typs. Dadurch wurden die ursprünglichen Instanzattribute natürlich zu den aktuellen Prototypattributen. Das zweite Problem bei der Prototypenkette besteht darin, dass beim Erstellen einer Instanz eines Untertyps keine Parameter an den Konstruktor des Obertyps übergeben werden können. Tatsächlich sollte gesagt werden, dass es keine Möglichkeit gibt, Parameter an den Konstruktor eines Supertyps zu übergeben, ohne dass sich dies auf alle Objektinstanzen auswirkt. Aus diesem Grund und wegen der Probleme, die durch die gerade besprochene Aufnahme von Referenztypwerten in Prototypen entstehen, werden Prototypketten in der Praxis selten allein verwendet.
2. Borrowing-Konstruktor
Um die Probleme zu lösen, die durch die Aufnahme von Referenztypwerten in Prototypen entstehen, begannen Entwickler, eine Methode namens „Borrowing-Konstruktor“ (Konstruktordiebstahl) zu verwenden. Technik (manchmal auch als gefälschte Objekte oder klassische Vererbung bezeichnet). Die Grundidee dieser Technik ist recht einfach: Der Supertyp-Konstruktor wird innerhalb des Subtyp-Konstruktors aufgerufen. Vergessen Sie nicht, dass Funktionen nichts anderes als Objekte sind, die Code in einer bestimmten Umgebung ausführen. Mit den Methoden apply() und call() können Sie also auch Konstruktoren für (in Zukunft) neu erstellte Objekte ausführen.
function Person(name){ this.name=name; } Person.property.doAction=function(){ alert(“talk”); } Person.property.showName=function(){ alert(this.name); } function Student(){ Person.call(this,name); this.age=5; }
Wenn Sie den Konstruktor nur ausleihen, werden Sie die Probleme des Konstruktormusters nicht vermeiden können - Die Methoden sind alle im Konstruktor definiert, sodass eine Wiederverwendung von Funktionen nicht in Frage kommt . Darüber hinaus sind im Prototyp des Supertyps definierte Methoden auch für Subtypen unsichtbar. Daher können alle Typen nur das Konstruktormuster verwenden. Angesichts dieser Probleme wird die Technik des Ausleihens von Konstruktoren selten allein verwendet.
3. Kombinationsvererbung
Kombinationsvererbung, manchmal auch pseudoklassische Vererbung genannt, bezieht sich auf die Kombination der Prototypenkette und der Ausleihe von Konstruktortechniken, um das Beste aus beiden zu nutzen. Die Idee dahinter besteht darin, die Prototypenkette zu verwenden, um die Vererbung von Prototypeigenschaften und -methoden sowie die Vererbung von Instanzeigenschaften durch Ausleihen von Konstruktoren zu erreichen. Auf diese Weise wird die Wiederverwendung von Funktionen durch die Definition von Methoden im Prototyp erreicht, und jede Instanz verfügt garantiert über ihre eigenen Attribute.
function Person(name){ this.name=name; this.loves=[“sing”,”paly games”] } Person.property.showLoves=function (){ alert(this.lovers); } function Student(name,age){ Person.class(this,name); This.age=age; } Student.property=new Person(); Student.property.constructor=Student; Student.property.showName=function(){ alert(this.name); }
Kombinierte Vererbung vermeidet die Mängel von Prototypketten und geliehenen Konstruktoren, kombiniert ihre Vorteile und wird zum am häufigsten verwendeten Vererbungsmuster in JavaScript. Darüber hinaus können „instanceof“ und „isPrototypeOf()“ auch zur Identifizierung von Objekten verwendet werden, die auf der Grundlage kombinierter Vererbung erstellt wurden.
4. Prototypische Vererbung
function object(o){ function F(){} F.prototype = o; return new F(); }
Wenn Sie keinen großen Aufwand betreiben müssen, um einen Konstruktor zu erstellen, sondern nur ein ähnliches Objekt beibehalten möchten Bei einem anderen Objekt ist die prototypische Vererbung voll funktionsfähig. Vergessen Sie jedoch nicht, dass Eigenschaften, die Referenztypwerte enthalten, immer den entsprechenden Wert gemeinsam nutzen, genau wie bei der Verwendung des Prototypmusters.
5. Parasitäre kombinierte Vererbung
Die sogenannte parasitäre kombinierte Vererbung bedeutet die Vererbung von Eigenschaften durch Ausleihen von Konstruktoren und Vererbungsmethoden durch die Hybridform der Prototypenkette. Die Grundidee hinter
ist: Es ist nicht nötig, den Konstruktor des Supertyps aufzurufen, um den Prototyp des Subtyps anzugeben. Alles, was wir brauchen, ist nichts weiter als eine Kopie des Prototyps des Supertyps
. Im Wesentlichen verwenden Sie die parasitäre Vererbung, um den Prototyp des Supertyps zu erben, und weisen das Ergebnis dann dem Prototyp des Subtyps zu
. Das Grundmuster der parasitären kombinatorischen Vererbung ist wie folgt.
function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //创建对象 prototype.constructor = subType; //增强对象 subType.prototype = prototype; //指定对象 }
个参数:子类型构造函数和超类型构造函数。在函数内部,第一步是创建超类型原型的一个副本。第二步是为创建的副本添加constructor 属性,从而弥补因重写原型而失去的默认的constructor 属性。最后一步,将新创建的对象(即副本)赋值给子类型的原型。这样,我们就可以用调用inheritPrototype()函数的语句,去替换前面例子中为子类型原型赋值的语句了。
集寄生式继承和组合继承的优点与一身,是实现基于类型继承的最有效方式。
以上就是JavaScript面向对象编程(继承实现方式)的内容,更多相关内容请关注PHP中文网(www.php.cn)!