Heim  >  Artikel  >  Web-Frontend  >  Lernen Sie objektorientiertes Javascript und die Implementierung der Vererbung in Javascript_Javascript-Kenntnissen

Lernen Sie objektorientiertes Javascript und die Implementierung der Vererbung in Javascript_Javascript-Kenntnissen

WBOY
WBOYOriginal
2016-05-16 15:22:061073Durchsuche

Das Beispiel in diesem Artikel stellt sechs Möglichkeiten zur Implementierung der Vererbung in JavaScript vor und stellt sie Ihnen als Referenz zur Verfügung. Der spezifische Inhalt ist wie folgt:

1. [Prototyp-Kettenvererbung] Der Kern der Implementierung besteht darin, das Prototypobjekt neu zu schreiben und es durch eine Instanz eines neuen Typs zu ersetzen. Tatsächlich wurde nicht die Konstruktor-Eigenschaft des SubType-Prototyps neu geschrieben, sondern der SubType-Prototyp zeigt auf ein anderes Objekt – den SuperType-Prototyp, und die Konstruktor-Eigenschaft dieses Prototyp-Objekts zeigt auf SuperType

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
 return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());//true

[Hinweis 1] Definieren Sie Methoden sorgfältig. Der Code zum Hinzufügen von Methoden zum Prototyp muss nach der Anweisung platziert werden, die den Prototyp ersetzt

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();

//添加了新方法
SubType.prototype.getSubValue = function(){
 return this.subproperty;
}
//重写超类型的方法
SubType.prototype.getSuperValue = function(){
 return false;
}
var instance = new SubType();
alert(instance.getSuperValue());//false

[Hinweis 2] Wenn Sie die Vererbung über die Prototypenkette implementieren, können Sie keine Objektliterale verwenden, um Prototypenmethoden zu erstellen. Dadurch wird die Prototypenkette überschrieben.

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();

//使用字面量方法添加新方法会导致上一行代码无效
SubType.prototype = {
 getSubValue : function(){
  return this,subproperty;
 },
 someOtherMethod : function(){
  return false;
 }
};
var instance = new SubType();
alert(instance.getSuperValue());//error

[Nachteil 1] Beim Erstellen einer Instanz eines Untertyps können Parameter nicht an den Konstruktor des Obertyps übergeben werden
[Nachteil 2] Prototypeigenschaften, die Referenztypwerte enthalten, werden von allen Instanzen gemeinsam genutzt

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){}
//继承了SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push('black');
alert(instance1.colors);//'red,blue,green,black'
var instance2 = new SubType();
alert(instance2.colors);//'red,blue,green,black'

2. [Geliehene Konstruktorvererbung (auch als Fake-Objekt oder klassische Vererbung bezeichnet)] ruft den Supertyp-Konstruktor innerhalb des -Subtyp-Konstruktors auf, sodass auch Konstruktoren mithilfe der Methoden apply() und call() verwendet werden können Wird in Zukunft auf neu erstellten Objekten ausgeführt

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){
 //继承了SuperType
 SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push('black');
alert(instance1.colors);//'red,blue,green,black'
var instance2 = new SubType();
alert(instance2.colors);//'red,blue,green'

[Vorteile] Übergabeparameter

function SuperType(name){
 this.name = name;
}
function SubType(){
 //继承了SUperType,同时还传递了参数
 SuperType.call(this,"Nicholas");
 //实例属性
 this.age = 29;
}
var instance = new SubType();
alert(instance.name);//"Nicholas"
alert(instance.age);//29 

[Hinweis] Um sicherzustellen, dass der SuperType-Konstruktor die Eigenschaften des Subtyps nicht überschreibt, können Sie Eigenschaften hinzufügen, die im Subtyp definiert werden sollen, nachdem Sie den Supertype-Konstruktor
aufgerufen haben

function SuperType(name){
 this.name = name;
 this.age = 30;
}
function SubType(){
 //实例属性
 this.age = 29;
 //继承了SUperType,同时还传递了参数
 SuperType.call(this,"Nicholas");
}
var instance = new SubType();
//实例属性被重写为SuperType构造函数的属性
alert(instance.age);//30

[Nachteil 1] Die Wiederverwendung von Funktionen kann nicht erreicht werden
[Nachteil 2] Im Prototyp des Supertyps definierte Methoden sind auch für den Subtyp unsichtbar. Daher können alle Typen nur das Konstruktormuster
verwenden 3. [Kombinierte Vererbung (auch pseudoklassische Vererbung genannt)] Ein Vererbungsmodell, das die Technologie der Prototypenverkettung und der Kreditaufnahme von Konstruktoren kombiniert, um die Stärken beider 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 es kann garantiert werden, dass jede Instanz ihre eigenen Attribute hat, was es zum am häufigsten verwendeten Vererbungsmuster in JavaScript macht.

function SuperType(name){
 this.name = name;
 this.colors = ['red','blue','green'];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 //继承属性
 SuperType.call(this,name);
 this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
 alert(this.age);
}
var instance1 = new SubType("Nicholas",29);
instance1.colors.push("black");
alert(instance1.colors);//'red,blue,green,black'
instance1.sayName();//"Nicholas"
instance1.sayAge();//29
var instance2 = new SubType("Greg",27);
alert(instance2.colors);//'red,blue,green'
instance2.sayName();//"Greg"
instance2.sayAge();//27

[Nachteile] In jedem Fall wird der Supertyp-Konstruktor zweimal aufgerufen: einmal beim Erstellen des Subtyp-Prototyps und einmal innerhalb des Subtyp-Konstruktors. Der Subtyp enthält schließlich alle Instanzeigenschaften des Supertypobjekts, muss diese Eigenschaften jedoch überschreiben, wenn der Subtypkonstruktor aufgerufen wird.

function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name); // 第二次调用SuperType()
 this.age = age;
}
SubType.prototype = new SuperType(); //第一次调用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
 alert(this.age);
}; 

4. [Prototypische Vererbung] Mithilfe von Prototypen können Sie neue Objekte basierend auf vorhandenen Objekten erstellen, ohne benutzerdefinierte Typen erstellen zu müssen. Im Wesentlichen führt object() eine flache Kopie des übergebenen Objekts aus.
[Hinweis] Für die prototypische Vererbung muss ein Objekt vorhanden sein, das als Basis für ein anderes Objekt verwendet werden kann. Wenn ein solches Objekt vorhanden ist, können Sie es an die Funktion object () übergeben und das erhaltene Objekt dann entsprechend ändern Bedürfnisse

function object(o){
  function F(){};
  F.prototype = o;
  return new F();
}
var person = {
  name: "Nicholas",
  friends: ["Shelby","Court","Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"

【4.1】【Object.create()-Methode】: Die neue Object.create()-Methode von ECMAScript5 standardisiert die prototypische Vererbung. Diese Methode akzeptiert zwei Parameter: ein Objekt, das als Prototyp des neuen Objekts verwendet wird, und (optional) ein Objekt zum Definieren zusätzlicher Eigenschaften für das neue Objekt. Wenn ein Parameter übergeben wird, verhalten sich die Methoden Object.create() und object() gleich

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"

[Hinweis] Der zweite Parameter der Object.create()-Methode hat das gleiche Format wie der zweite Parameter der Object.defineProperties()-Methode: Jede Eigenschaft wird durch ihren eigenen Deskriptor definiert. Jede auf diese Weise angegebene Eigenschaft überschreibt die gleichnamige Eigenschaft des Prototypobjekts.

var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person,{
 name: {
  value: "Greg"
 }
});
alert(anotherPerson.name);//"Greg" 

【4.2】Kompatibel mit der Object.create()-Methode in Browsern niedrigerer Versionen

if(typeof Object.create != "function"){
 (function(){
  var F = function(){};
  Object.create = function(o){
   if(arguments.length > 1){
    throw Error('Second argument noe supported');
   }
   if(o === null){
    throw Error("Cannot set a null [[Prototype]]");
   }
   if(typeof o != 'Object'){
    throw TypeError("Arguments must be an object");
   }
   F.prototype = o;
   return new F();
  }
 })();
} 

5. [Parasitäre Vererbung] Erstellen Sie eine Funktion, die nur dazu dient, den Vererbungsprozess in gewisser Weise zu kapseln, und sieht schließlich so aus, als hätte sie wirklich die ganze Arbeit erledigt das gleiche Objekt
[Nachteil] Die Wiederverwendung von Funktionen kann nicht erreicht werden

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function createAnother(original){
 var clone = object(original);//通过调用函数创建一个新对象
 clone.sayHi = function(){ //以某种方式来增强这个对象
  alert("hi");
 };
 return clone;//返回这个对象
}
var person = {
 name: "Nicholas",
 friends: ["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//"hi"

6. [Parasitäre Kombinationsvererbung] Eigenschaften durch Ausleihen von Konstruktoren und Methoden durch die Hybridform der Prototypenkette erben. Die Grundidee dahinter ist, dass statt den Konstruktor des Supertyps aufzurufen, um den Prototyp eines Subtyps anzugeben, lediglich eine Kopie des Prototyps des Supertyps benötigt wird. Im Wesentlichen verwenden Sie die parasitäre Vererbung, um vom Prototyp des Supertyps zu erben und das Ergebnis dann dem Prototyp des Subtyps zuzuweisen. Die parasitäre kombinierte Vererbung ist das idealste Vererbungsparadigma für Referenztypen.

//这个例子中的高效率体现在它只调用了一次Super构造函数,并且因此避免了在SubType.prototype上面创建不必要的、多余的属性。与此同时,原型链还能保持不变。
function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function inheritPrototype(subType,superType){
 var prototype = object(superType.prototype);//创建对象
 prototype.constructor = subType;//增强对象
 subType.prototype = prototype;//指定对象
}
function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name);
 this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
 alert(this.age);
}

Das Obige ist der gesamte Inhalt dieses Artikels, die Art und Weise, wie die Vererbung in JavaScript implementiert wird. Vielen Dank an alle für das Lesen und der Herausgeber wird weiterhin hart arbeiten!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn