Heim > Artikel > Web-Frontend > Detaillierte Erklärung der Vererbung in JavaScript
js
Die folgenden zwei Vererbungsmethoden werden häufig verwendet in:
Prototypkettenvererbung (Vererbung zwischen Objekten)
Klassische Vererbung (Vererbung zwischen Konstruktoren)
Da js
keine echte objektorientierte Sprache wie java
ist, ist js
objektbasiert und hat keine Klassen. Konzept. Wenn Sie also die Vererbung implementieren möchten, können Sie den Prototypmechanismus von js
verwenden oder die Methoden apply
und call
verwenden, um
zu implementieren. In objektorientierten Sprachen verwenden wir 类
um eine automatische Definition von Objekten zu erstellen. Allerdings ist alles in js
ein Objekt. Wie erstellt man also ein benutzerdefiniertes Objekt? Dies erfordert die Verwendung des Prototyps von js
:
Wir können prototype
einfach als Vorlage betrachten, und die neu erstellten benutzerdefinierten Objekte sind alle Kopien dieser Vorlage (prototype
) ( Tatsächlich Es handelt sich nicht um eine Kopie, sondern um einen Link, aber dieser Link ist unsichtbar. Im neu instanziierten Objekt befindet sich ein unsichtbarer __Proto__
-Zeiger, der auf das Prototypobjekt zeigt.
js
Sie können die Funktionen der Implementierungsklasse durch Konstruktoren und Prototypen simulieren. Darüber hinaus js
Die Implementierung der Klassenvererbung basiert auch auf der Prototypenkette.
类式继承
besteht darin, den Supertyp-Konstruktor innerhalb des Subtyp-Konstruktors aufzurufen.
Strikte Klassenvererbung ist nicht sehr verbreitet. Sie wird normalerweise in Kombination verwendet:
function Super(){ this.colors=["red","blue"]; } function Sub(){ Super.call(this); }
原型式继承
besteht darin, mithilfe vorhandener Objekte ein neues Objekt zu erstellen und den Prototyp davon zu konvertieren Das Verweisen der Unterklasse auf die übergeordnete Klasse entspricht dem Beitritt zur Prototypenkette der übergeordneten Klasse
Damit die Unterklasse die Attribute (einschließlich Methoden) der übergeordneten Klasse erbt , müssen Sie zunächst eine Strukturfunktion definieren. Weisen Sie dann die neue Instanz der übergeordneten Klasse dem Prototyp des Konstruktors zu. Der Code lautet wie folgt:
<script> function Parent(){ this.name = 'mike'; } function Child(){ this.age = 12; } Child.prototype = new Parent();//Child继承Parent,通过原型,形成链条 var test = new Child(); alert(test.age); alert(test.name);//得到被继承的属性 //继续原型链继承 function Brother(){ //brother构造 this.weight = 60; } Brother.prototype = new Child();//继续原型链继承 var brother = new Brother(); alert(brother.name);//继承了Parent和Child,弹出mike alert(brother.age);//弹出12 </script>
Es fehlt noch ein Glied in der obigen Prototyp-Kettenvererbung, nämlich Object
, und alle Konstruktoren erben von Object
. Die Vererbung Object
erfolgt automatisch und erfordert keine manuelle Vererbung. Was ist also ihre Zugehörigkeit?
Die Beziehung zwischen Prototypen und Instanzen kann auf zwei Arten bestimmt werden. Operatoren instanceof
und isPrototypeof()
Methoden:
alert(brother instanceof Object)//true alert(test instanceof Brother);//false,test 是brother的超类 alert(brother instanceof Child);//true alert(brother instanceof Parent);//true
Solange es sich um einen Prototyp handelt, der in der Prototypenkette erscheint, kann man sagen, dass es sich um den Prototyp der aus der Prototypenkette abgeleiteten Instanz handelt. Daher gibt die Methode isPrototypeof()
auch true
zurück. In js
wird die geerbte Funktion als Supertyp bezeichnet (übergeordnete Klasse, Basisklasse ist ebenfalls akzeptabel) und die geerbte Funktion wird als Supertyp bezeichnet Untertyp (Unterklasse, abgeleitete Klasse). Es gibt zwei Hauptprobleme bei der Verwendung der Prototypenvererbung:
Erstens wird durch das wörtliche Umschreiben des Prototyps die Beziehung unterbrochen, wobei der Prototyp des Referenztyps verwendet wird und der Untertyp keine Parameter an den Obertyp übergeben kann.
Pseudoklassen lösen das Problem der Referenzfreigabe und der Unfähigkeit, Parameter von Supertypen zu übergeben. Wir können die „geliehene Konstruktor“-Technologie verwenden
<script> function Parent(age){ this.name = ['mike','jack','smith']; this.age = age; } function Child(age){ Parent.call(this,age); } var test = new Child(21); alert(test.age);//21 alert(test.name);//mike,jack,smith test.name.push('bill'); alert(test.name);//mike,jack,smith,bill </script>
Obwohl das Ausleihen von Konstruktoren die beiden gerade genannten Probleme löst, ist eine Wiederverwendung ohne einen Prototyp unmöglich, daher benötigen wir das 原型链+借用构造函数
Muster, das als kombinierte Vererbung bezeichnet wird
<script> function Parent(age){ this.name = ['mike','jack','smith']; this.age = age; } Parent.prototype.run = function () { return this.name + ' are both' + this.age; }; function Child(age){ Parent.call(this,age);//对象冒充,给超类型传参 } Child.prototype = new Parent();//原型链继承 var test = new Child(21);//写new Parent(21)也行 alert(test.run());//mike,jack,smith are both21 </script>
Kombinierte Vererbung ist eine häufig verwendete Vererbungsmethode. Die Idee dahinter besteht darin, die Prototypenkette zum Erben von Prototypeigenschaften und -methoden zu verwenden und Konstruktoren zum Erben von Instanzeigenschaften auszuleihen. 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. Verwendung von
call()
: Rufen Sie eine Methode eines Objekts auf, um das aktuelle Objekt durch ein anderes Objekt zu ersetzen.
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
Diese Art der Vererbung verwendet Prototypen, um neue Objekte basierend auf vorhandenen Objekten zu erstellen, ohne benutzerdefinierte Typen zu erstellen >Prototypische Vererbung erstellt zunächst einen temporären Konstruktor innerhalb der Funktion 原型式继承
, verwendet dann das übergebene Objekt als Prototyp dieses Konstruktors und gibt schließlich eine neue Instanz dieses temporären Typs zurück.
<script> function obj(o){ function F(){} F.prototype = o; return new F(); } var box = { name : 'trigkit4', arr : ['brother','sister','baba'] }; var b1 = obj(box); alert(b1.name);//trigkit4 b1.name = 'mike'; alert(b1.name);//mike alert(b1.arr);//brother,sister,baba b1.arr.push('parents'); alert(b1.arr);//brother,sister,baba,parents var b2 = obj(box); alert(b2.name);//trigkit4 alert(b2.arr);//brother,sister,baba,parents </script>Parasitäre Vererbung
obj()
Diese Vererbungsmethode kombiniert den Prototyp + das Fabrikmuster, um den Erstellungsprozess zu kapseln.
<script> function create(o){ var f= obj(o); f.run = function () { return this.arr;//同样,会共享引用 }; return f; } </script>, aber der Supertyp der kombinierten Vererbung wird während der Verwendung zweimal aufgerufen Subtyp und ein anderes Mal im Subtyp-Konstruktor
Der obige Code ist die vorherige kombinierte Vererbung, sodass die parasitäre kombinierte Vererbung das Problem von zwei Aufrufen löst. js
<script> function Parent(name){ this.name = name; this.arr = ['哥哥','妹妹','父母']; } Parent.prototype.run = function () { return this.name; }; function Child(name,age){ Parent.call(this,age);//第二次调用 this.age = age; } Child.prototype = new Parent();//第一次调用 </script>Aufrufen und AnwendenGlobale Funktionen
<script> function obj(o){ function F(){} F.prototype = o; return new F(); } function create(parent,test){ var f = obj(parent.prototype);//创建对象 f.constructor = test;//增强对象 } function Parent(name){ this.name = name; this.arr = ['brother','sister','parents']; } Parent.prototype.run = function () { return this.name; }; function Child(name,age){ Parent.call(this,name); this.age =age; } inheritPrototype(Parent,Child);//通过这里实现继承 var test = new Child('trigkit4',21); test.arr.push('nephew'); alert(test.arr);// alert(test.run());//只共享了方法 var test2 = new Child('jack',22); alert(test2.arr);//引用问题解决 </script>und
apply
call
Das Obige ist die detaillierte Erklärung der Vererbungsmethoden in JavaScript. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)! this
// 定义一个全局函数 function foo() { console.log(this.fruit); } // 定义一个全局变量 var fruit = "apple"; // 自定义一个对象 var pack = { fruit: "orange" }; // 等价于window.foo(); foo.apply(window); // "apple",此时this等于window // 此时foo中的this === pack foo.apply(pack); // "orange"