Heim > Web-Frontend > js-Tutorial > Was sind die Vererbungsmethoden in js?

Was sind die Vererbungsmethoden in js?

PHP中文网
Freigeben: 2017-06-21 09:57:37
Original
1140 Leute haben es durchsucht

1 Vererbung in ES6

ES6 verwendet das Schlüsselwort „class“, um Klassen zu definieren, und das Schlüsselwort „extends“, um Klassen zu erben. Die Super-Methode muss im Konstruktor der Unterklasse aufgerufen werden, um das „diese“ Objekt der übergeordneten Klasse zu erhalten. Beim Aufruf von super können Sie Parameter an den übergeordneten Konstruktor übergeben. Unterklassen können die Eigenschaften und Methoden der übergeordneten Klasse direkt über das Superobjekt verwenden oder die Definitionen in der übergeordneten Klasse über gleichnamige Eigenschaften oder Methoden überschreiben.

class Father {
  constructor () {
    this.surname = '王'
    this.money = Infinity
  }
  sayName () {
    console.log(`My surname is ${this.surname}.`)
  }
}

class Son extends Father {
  constructor (firstname) {
    super()
    this.firstname = firstname
  }
  sayName () {
    console.log(`My name is ${super.surname}${this.firstname}.`)
  }
  sayMoney () {
    console.log(`I have ${this.money} money.`)
  }
}

let Sephirex = new Son('撕葱')
Sephirex.sayName()
Sephirex.sayMoney()
Nach dem Login kopieren

Klassen und Vererbung in ES6 sind im Wesentlichen syntaktischer Zucker, der mithilfe von Prototypen implementiert wird. Die in der Klasse definierten Methoden entsprechen dem Definieren von Methoden in der Konstruktormethode. super Die Methode entspricht dem Aufruf des Konstruktors der übergeordneten Klasse in der Unterklasse. Lassen Sie uns weiterhin die Implementierung der Vererbung in ES5 diskutieren.

2 Prototypkettenvererbung

Das Grundmuster der Prototypkettenvererbung besteht darin, das Prototypobjekt des Untertyps auf eine Instanz des übergeordneten Typs verweisen zu lassen und dann Methoden für seinen Prototyp zu erweitern.

function Person (name) {
  this.name = name
  this.likes = ['apple', 'orange']
}
Person.prototype.sayName = function () {
  console.log(this.name)
}

function Worker () {
  this.job = 'worker'
}
Worker.prototype = new Person()
Worker.prototype.sayJob = function () {
  console.log(this.job)
}

let Tom = new Worker()
let Jerry = new Worker()
Tom.likes.push('grape')
console.log(Jerry.likes) // [ 'apple', 'orange', 'purple' ]
Nach dem Login kopieren

Prinzip: Im vorherigen Artikel haben wir __proto__ und Prototyp besprochen. In der Instanz der Unterklasse gibt es einen __proto__-Zeiger, der auf das Prototypobjekt seines Konstruktors zeigt. Der Prototyp des Konstruktors der Unterklasse zeigt auf eine Instanz der übergeordneten Klasse, und __proto__ in der Instanz der übergeordneten Klasse zeigt auf den Prototyp des Konstruktors der übergeordneten Klasse ... Auf diese Weise wird eine Prototypenkette gebildet.
Es ist zu beachten, dass das Referenztypattribut in der übergeordneten Klasse, selbst wenn es im Konstruktor definiert ist, dennoch von der Instanz der untergeordneten Klasse gemeinsam genutzt wird. Dies liegt daran, dass der Prototyp des Unterklassenkonstruktors tatsächlich eine Instanz der übergeordneten Klasse ist, sodass die Instanzeigenschaften der übergeordneten Klasse natürlich zu Prototypeigenschaften der Unterklasse werden und die Prototypeigenschaften von Referenztypwerten zwischen Instanzen gemeinsam genutzt werden.
Ein weiteres Problem mit der Prototypenkette besteht darin, dass es keine Möglichkeit gibt, Parameter an den Konstruktor der übergeordneten Klasse zu übergeben, ohne alle Objektinstanzen zu beeinflussen. Wenn Sie wie im obigen Beispiel Worker.prototype = new Person() verwenden, um den Prototyp der Unterklasse auf die Instanz der übergeordneten Klasse zu verweisen, werden bei der Übergabe von Initialisierungsparametern die Instanznamenattribute aller Unterklassen als Parameter übergeben. Wenn hier keine Parameter übergeben werden, besteht später keine Möglichkeit, Parameter an den Konstruktor der übergeordneten Klasse zu übergeben. Daher wird das Vererbungsmuster der Prototypkette selten allein verwendet.

3 Ausleihen von Konstruktoren

Ausleihen von Konstruktoren kann das Problem gemeinsamer Referenztypattribute lösen. Das sogenannte „Ausleihen“ eines Konstruktors besteht darin, den Konstruktor der übergeordneten Klasse im Konstruktor der Unterklasse aufzurufen. Vergessen Sie nicht, dass der Sinn dieser Funktion in der Funktion nichts damit zu tun hat, wo die Funktion definiert ist nur mit wo es heißt. Wir können call oder apply verwenden, um den Konstruktor der übergeordneten Klasse für die Unterklasseninstanz aufzurufen und die Eigenschaften und Methoden der übergeordneten Klasse abzurufen, ähnlich wie beim Aufrufen der Supermethode im ES6-Unterklassenkonstruktor.

function Person (name) {
  this.name = name
  this.likes = ['apple', 'orange']
}

function Worker (name) {
  Person.call(this, name)
  this.job = 'worker'
}

let Tom = new Worker('Tom')
Tom.likes.push("grape")

let Jerry = new Worker('Jerry')

console.log(Tom.likes) // [ 'apple', 'orange', 'grape' ]
console.log(Jerry.likes) // [ 'apple', 'orange' ]
Nach dem Login kopieren

Das Problem bei der einfachen Verwendung des Konstruktors besteht darin, dass die Funktion nicht wiederverwendet werden kann und die Unterklasse die Attribute und Methoden des übergeordneten Klassenprototyps nicht erhalten kann.

4 Kombinationsvererbung

Die Kombinationsvererbung leiht sich Konstruktoren aus, um Instanzeigenschaften zu definieren, und verwendet Methoden zur gemeinsamen Nutzung von Prototypketten. Durch die Kombination der Vererbung werden der Prototypkettenmodus und der geliehene Konstruktor kombiniert, wodurch die Stärken beider genutzt und ihre jeweiligen Mängel ausgeglichen werden. Dies ist der am häufigsten verwendete Vererbungsmodus in js.

function Person (name) {
  this.name = name
  this.likes = ['apple', 'orange']
}
Person.prototype.sayName = function () {
  console.log(this.name)
}

function Worker (name, job) {
  Person.call(this, name) // 第二次调用 Person()
  this.job = job
}
Worker.prototype = new Person() // 第一次调用 Person()
Worker.prototype.constructor = Worker
Worker.prototype.sayJob = function () {
  console.log(this.job)
}

let Tom = new Worker('Tom', 'electrician')
Tom.likes.push('grape')
console.log(Tom.likes) // [ 'apple', 'orange', 'grape' ]
Tom.sayName() // Tom
Tom.sayJob() // electrician

let Jerry = new Worker('Jerry', 'woodworker')
console.log(Jerry.likes) // [ 'apple', 'orange' ]
Jerry.sayName() // Jerry
Jerry.sayJob() // woodworker
Nach dem Login kopieren

Die kombinierte Vererbung ist nicht ohne Mängel, das heißt, der Vererbungsprozess ruft den Konstruktor der übergeordneten Klasse zweimal auf. Wenn der Person-Konstruktor zum ersten Mal aufgerufen wird, erhält Worker.prototype zwei Attribute: Name und Likes. Wenn der Worker-Konstruktor aufgerufen wird, wird der Person-Konstruktor erneut aufgerufen, und dieses Mal werden die Instanzattribute Name und Likes direkt erstellt , deckt zwei Eigenschaften mit demselben Namen im Prototyp ab.

5 Prototypische Vererbung

Die folgende Objektfunktion wurde in einem Artikel von Douglas Crockford aufgezeichnet. Innerhalb der Objektfunktion wird zunächst ein temporärer Konstruktor erstellt, dann wird das übergebene Objekt als Prototyp dieses Konstruktors verwendet und schließlich wird eine neue Instanz dieses temporären Typs zurückgegeben. Im Wesentlichen führt object() eine flache Kopie des übergebenen Objekts aus. Diese Vererbungsmethode entspricht dem Kopieren der Eigenschaften und Methoden des übergeordneten Typs in den Untertyp und dem anschließenden Hinzufügen der entsprechenden Eigenschaften und Methoden zum Untertyp.
Diese Methode teilt auch Eigenschaften von Referenztypwerten.

function object(o){
  function F(){}
  F.prototype = o;
  return new F();
}

let Superhero = {
  name: 'Avenger',
  skills: [],
  sayName: function () {
    console.log(this.name)
  }
}

let IronMan = object(Superhero)
IronMan.name = 'Tony Stark'
IronMan.skills.push('fly')

let CaptainAmerica = object(Superhero)
CaptainAmerica.name = 'Steve Rogers'
CaptainAmerica.skills.push('shield')

IronMan.sayName() // Tony Stark
console.log(IronMan.skills) // [ 'fly', 'shield' ]
Nach dem Login kopieren

ES5 verwendet die Methode Object.create(), um die prototypische Vererbung zu standardisieren. 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. Object.create() verhält sich genauso wie die Methode object(), wenn ein Argument übergeben wird. Der zweite Parameter der Methode Object.create() hat das gleiche Format wie der zweite Parameter der Methode Object.defineProperties().

let CaptainAmerica = Object.create(Superhero, {
  name: {
    value: 'Steve Rogers',
    configurable: false
  }
})
Nach dem Login kopieren

6 Parasitäre Vererbung

Parasitäre Vererbung ist einfach zu verstehen. Es handelt sich lediglich um eine Fabrikfunktion, die den Vererbungsprozess kapselt. Da Methoden direkt am Objekt definiert werden, können durch parasitäre Vererbung hinzugefügte Methoden nicht wiederverwendet werden.

function inherit(parent){
  var clone = Object.create(parent)
  clone.name = 'hulk'
  clone.sayHi = function(){
    console.log("hi")
  }
  return clone
}

let Hulk = inherit(Superhero)

Hulk.sayName() // hulk
Hulk.sayHi() // hi
Nach dem Login kopieren

7 Parasitäre kombinierte Vererbung

Wie bereits erwähnt, ist die kombinierte Vererbung die am häufigsten verwendete Vererbungsmethode in js. Der Nachteil besteht jedoch darin, dass der Konstruktor der übergeordneten Klasse zweimal aufgerufen wird . Parasitäre kompositorische Vererbung kann dieses Problem lösen und gilt als die idealste Vererbungsmethode für Objekte, die Referenztypwerte enthalten.
Die Grundidee der parasitären kombinierten Vererbung besteht darin, dass der Konstruktor der übergeordneten Klasse nicht aufgerufen werden muss, um den Prototyp der Unterklasse anzugeben. Es ist lediglich eine Kopie des Prototyps der übergeordneten Klasse erforderlich . Bei der parasitären kompositorischen Vererbung werden Eigenschaften durch Entleihen von Konstruktoren geerbt und anschließend mithilfe der parasitären Vererbung der Prototyp der übergeordneten Klasse geerbt.

function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype)
  prototype.constructor = subType
  subType.prototype = prototype
}

function Person (name) {
  this.name = name
  this.likes = ['apple', 'orange']
}
Person.prototype.sayName = function () {
  console.log(this.name)
}

function Worker (name, job) {
  Person.call(this, name)
  this.job = job
}
inheritPrototype(Worker, Person)

Worker.prototype.sayJob = function () {
  console.log(this.job)
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWas sind die Vererbungsmethoden in js?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage