Heim  >  Artikel  >  Web-Frontend  >  Drei Möglichkeiten und Beispiele der Vererbung in JavaScript_Javascript-Kenntnissen

Drei Möglichkeiten und Beispiele der Vererbung in JavaScript_Javascript-Kenntnissen

WBOY
WBOYOriginal
2016-05-16 16:17:081070Durchsuche

Obwohl JavaScript eine objektorientierte Sprache ist, unterscheidet sich ihr Vererbungsmechanismus von Anfang an von anderen herkömmlichen objektorientierten Sprachen. Es handelt sich um einen prototypbasierten Vererbungsmechanismus, aber unter diesem Mechanismus ist die Vererbung immer noch vorhanden Es gibt einige verschiedene Möglichkeiten, dies umzusetzen.

Methode 1: Klassenvererbung

Die sogenannte Klassenvererbung bezieht sich auf die Vererbungsmethode, die traditionelle objektorientierte Sprachen imitiert. Sowohl die Vererbung als auch die Vererbung sind „Klassen“.

Definieren Sie zunächst eine übergeordnete Klasse (oder Superklasse):


function Person(name){
    this.name=name;
  }

  Person.prototype.getName=function(){
    return this.name;
  };

Die Attribute der übergeordneten Klasse Person werden im Konstruktor definiert, wodurch sichergestellt wird, dass das Namensattribut der Unterklasse, die es erbt, dieses Attribut nicht mit ihr teilt, sondern nur zur Unterklasse gehört. Die getName-Methode wird auf der gemountet Prototyp, damit mehrere Instanzen seiner Unterklassen diesen Methodenkörper gemeinsam nutzen können, wodurch Speicher gespart werden kann (Bei jedem Erscheinen einer neuen Instanz wird sichergestellt, dass die getName-Methode dieser Instanzen auf denselben Speicherplatz verweist.) als ein separater Raum).

Definieren Sie eine Vererbungsmethode, die wie folgt erweitert wird:


function extend(subClass,superClass){
    var F=function(){};
    F.prototype=superClass.prototype;
    subClass.prototype=new F();
    subClass.prototype.constructor=subClass;

    subClass.superClass=superClass.prototype;
    if(superClass.prototype.constructor==Object.prototype.constructor){
      superClass.prototype.constructor=superClass;
    }

  }

Erstellen Sie bei dieser Methode zunächst eine neue Klasse F, machen Sie ihren Prototyp zum Prototyp der übergeordneten Klasse und lassen Sie den Prototyp der Unterklasse auf eine Instanz der Klasse F verweisen, wodurch der Zweck der Vererbung der übergeordneten Klasse erreicht wird. Da der Prototyp der Unterklasse geändert wurde, wird gleichzeitig das Konstruktorattribut des geänderten Prototyps auf die Unterklasse verwiesen, sodass sie über einen Konstruktor verfügt, und gleichzeitig wird ein SuperClass-Attribut in die Unterklasse eingebunden. Dadurch kann die Unterklasse die übergeordnete Klasse aufrufen und so die Beziehung zwischen der Unterklasse und der übergeordneten Klasse herstellen.

Definieren Sie wie folgt eine Unterklasse „Autor“, um die übergeordnete Klasse „Person“ zu erben:

function Author(name,books){
    Author.superClass.constructor.call(this,name);
    this.book=books;
  }
  extend(Author,Person);
  Author.prototype.getBooks=function(){
    return this.book;
  }

Hier wird im Konstruktor der Unterklasse der Konstruktor der übergeordneten Klasse über sein SuperClass-Attribut aufgerufen und die Aufrufmethode verwendet, um den von der Methode aufgerufenen Zeiger zu konvertieren, sodass der Autor der Unterklasse auch Eigentümer ist (erbt). ) Die Attribute der übergeordneten Klasse und gleichzeitig Die Unterklasse verfügt auch über ein eigenes Attributbuch, sodass im Konstruktor die Parameterbücher dem Attributbuch zugewiesen werden, um den Zweck der Konstruktion zu erreichen. Verwenden Sie die Erweiterungsfunktion, um die Eigenschaften und Methoden des Prototyps der übergeordneten Klasse Person zu erben (eigentlich werden nur die Methoden geerbt, da wir die Methoden zuvor nur an den Prototyp gemountet haben und die Eigenschaften im Konstruktor definiert wurden). Gleichzeitig verfügt der Autor über eine eigene Methode getBooks, die auf dem entsprechenden Prototyp montiert wird und den Zweck einer weiteren Erweiterung auf Basis der Vererbung erreicht.

Diese Vererbungsmethode verwendet offensichtlich eine Klassenvererbung, die der herkömmlichen objektorientierten Sprache ähnelt. Der Vorteil besteht darin, dass sie für Programmierer, die an traditionelle objektorientierte Konzepte gewöhnt sind, leicht zu verstehen ist Der Speicherverbrauch ist etwas größer, da die Unterklasse auch über einen eigenen Konstruktor und Prototyp verfügt und die Eigenschaften der Unterklasse und der übergeordneten Klasse vollständig isoliert sind. Auch wenn die beiden den gleichen Wert haben, können sie nicht denselben Speicher teilen.

Methode 2: Prototypische Vererbung

Definieren Sie zunächst eine übergeordnete Klasse. Dies imitiert nicht absichtlich die Verwendung von Konstruktoren zum Definieren, sondern verwendet direkt Objektliterale, um ein Objekt zu definieren, bei dem es sich um die übergeordnete Klasse handelt.


var Person={
   name:'default name',
   getName:function(){
     return this.name;
   }

 } ;

Wie die erste Methode verfügt dieses Objekt über einen Attributnamen und eine Methode getName.

Definieren Sie dann wie folgt eine Klonmethode, um die Vererbung der Unterklasse von der übergeordneten Klasse zu realisieren:


function clone(obj){
     function F(){}
     F.prototype=obj;
     return new F();
   }
Diese Klonmethode erstellt ein neues Objekt, verweist den Prototyp des Objekts auf die übergeordnete Klasse, bei der es sich um den Parameter obj handelt, und gibt gleichzeitig das Objekt zurück.

Schließlich erbt die Unterklasse die übergeordnete Klasse über die Klonfunktion wie folgt:


 var Author=clone(Person);
 Author.book=['javascript'];
 Author.showBook=function(){
 return this.book;
 }

这里定义一个子类,通过clone函数继承父类Person,同时拓展了一个属性book,和一个方法showBook,这里该子类也拥有属性name,但是它和父类的name值是一样的,所以没有进行覆盖,如果不一样,可以采用

 Author.name='new name';覆盖这个属性,从而得到子类的一个新的name属性值。

这种原型式继承相比于类式继承更为简单自然,同时如果子类的属性和父类属性值相同,可以不进行修改的话,那么它们两者其实共享的是同一段内存空间,如上面的name属性,缺点是对于习惯了传统面向对象的程序员难以理解,如果两者要进行选择的话,无疑是这种方式更为优秀一些。

既然javascript中采用基于原型的方式来实现继承,而且每个对象的原型只能指向某个特定的类的实例(不能指向多个实例),那么如何实现多重继承(即让一个类同时具有多个类的方法和属性,而且本身内部不自己定义这些方法和属性)?

在javascript设计模式中给出了一种掺元类(mixin class)的方式:

首先定义一个掺元类,用来保存一些常用的方法和属性,这些方法和属性可以通过拓展的方式添加到任何其他类上,从而被添加类就具有了该类的某些方法和属性,如果定义多个掺元类,同时添加给一个类,那么该类就是间接实现了“多重继承”,基于这种思想,实现如下:

掺元类定义:

var Mixin=function(){};
  Mixin.prototype={
    serialize:function(){
      var output=[];
      for(key in this){
        output.push(key+":"+this[key]);
      }
      return output.join(',');
    }
  }

该掺元类具有一个serialize方法,用来遍历其自身,输出自身的属性和属性值,并且将他们以字符串形式返回,中间用逗号隔开。

定义一个扩充方法,用来使某个类经过扩充之后具备掺元类的属性或方法,如下:

function augment(receivingClass,givingClass){
    if(arguments[2]){
      for(var i= 2,len=arguments.length;i<len;i++){
        receivingClass.prototype[arguments[i]]=givingClass.prototype[arguments[i]];
      }
    }
    else
    {
      for(methodName in givingClass.prototype){
        if(!receivingClass.prototype[methodName]){
          receivingClass.prototype[methodName]=givingClass.prototype[methodName];
        }
      }

    }
 }

该方法默认是两个参数,第一个参数是接受被扩充的类,第二个参数是掺元类(用来扩充其他类的类),还可以有其他参数,如果大于两个参数,后面的参数都是方法或者属性名,用来表示被扩充类只想继承掺元类的指定的属性或方法,否则默认继承掺元类的所有属性和方法,在该函数中,第一个if分支是用来继承指定属性和方法的情形,else分支是默认继承所有属性和方法的情形。该方法的实质是将掺元类的原型上的属性和方法都扩充(添加)到了被扩充类的原型上面,从而使其具有掺元类的属性和方法。

最后,使用扩充方法实现多重继承

augment(Author,Mixin);
   var author= new Author('js',['javascript design patterns']);
   alert(author.serialize());

这里定义了一个author的类,该类继承自Person父类,同时又具备掺元类Mixin的方法和属性,如果你愿意,可以定义N个掺元类用来扩充该类,它同样能够继承你定义的其他掺元类的属性和方法,这样就实现了多重继承,最后,author的serialize方法的运行结果如下:

你会发现该类同时具有person类,Author类,Mixin类的属性和方法,其中Person和Mixin的属性和方法都是通过“继承”得来的,从实际上来讲,它实现了多重继承。

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