Heim  >  Artikel  >  Web-Frontend  >  Tiefes Verständnis der prototypischen Vererbung von JavaScript

Tiefes Verständnis der prototypischen Vererbung von JavaScript

黄舟
黄舟Original
2017-02-21 11:19:19902Durchsuche



Das Wesen der Vererbung: Wiederverwendung

Bevor Sie die prototypische Vererbung in JavaScript besprechen, können Sie genauso gut darüber nachdenken, warum Vererbung erforderlich ist ?

Stellen Sie sich ein Szenario vor: Wenn wir zwei Objekte haben, haben einige davon die gleichen Eigenschaften und das andere unterschiedliche Eigenschaften. Normalerweise besteht eine gute Designlösung darin, dieselbe Logik zur Wiederverwendung zu extrahieren.

Nehmen Sie als Beispiel zwei Schüler xiaoMing liLei. Die beiden Klassenkameraden haben eigene Namen und stellen sich vor. Als Programmobjekt abstrahiert kann es wie folgt dargestellt werden.

var xiaoMing = {
  name : "xiaoMing",
  hello : function(){
    console.log( 'Hello, my name is '+ this.name + '.');
  }
}

var liLei = {
  name : "liLei",
  hello : function(){
    console.log( 'Hello, my name is '+ this.name  + '.');
  }
}

Studenten, die Java verwendet haben, denken möglicherweise zunächst darüber nach, dieses Problem objektorientiert zu lösen. Erstellen Sie eine Person-Klasse und instanziieren Sie zwei Objekte, xiaoMing und liLei. In ES6 gibt es auch ein Konzept, das den Klassen in Java ähnelt: class .

Im Folgenden wird die ES6-Syntax verwendet und objektorientierte Ideen verwendet, um den obigen Code zu rekonstruieren.

class Person {
  constructor(name){
    this.name = name
  }

  hello(){
    console.log(this.name);
  }
}

var xiaoMing = new Person('xiaoMing');
var liLei = new Person('liLei');

Wie Sie sehen, wird durch die Verwendung von Klassen zum Erstellen von Objekten der Zweck der Wiederverwendung erreicht. Die Logik, auf der es basiert, besteht darin, dass eine Vorlage abstrahiert werden kann und mehrere ähnliche Objekte entsprechend der Vorlage kopiert werden können, wenn zwei oder mehr Objekte ähnliche Strukturen und Funktionen haben.

Verwenden Sie Klassen, um Objekte zu erstellen, genau wie ein Fahrradhersteller, der immer wieder dieselben Baupläne verwendet, um viele Fahrräder zu bauen.

Natürlich gibt es mehr als eine Lösung für das Wiederverwendungsproblem. Traditionelle objektorientierte Klassen sind nur eine der Lösungen. Jetzt ist unser Protagonist an der Reihe, die „prototypische Vererbung“, die das Problem der Wiederverwendung aus einem anderen Blickwinkel löst.

Prinzip der Prototypenvererbung

Prototypobjekt

Objekt in JavaScript besteht aus zwei Teilen, einer Sammlung gewöhnlicher Eigenschaften und Prototypeigenschaften.

var o = {
  a : 'a',
  ...
  __proto__: prototypeObj
}

Gewöhnliche Attribute beziehen sich auf a; Prototypattribute beziehen sich auf __proto__. Dies war nicht Teil der Spezifikation. Später stellte Chrome die zugrunde liegenden Eigenschaften der Sprache über __proto__ offen, das nach und nach von allen akzeptiert und der ES6-Spezifikation hinzugefügt wurde. Der Wert von o.__proto__prototypObj ist Prototypobjekt. Das Prototypobjekt ist eigentlich ein gewöhnliches Objekt. Der Grund, warum es als Prototypobjekt bezeichnet wird, liegt einfach darin, dass es sich um den Wert handelt, auf den das Prototypattribut verweist.

Das Prototyp-Objekt ist etwas Besonderes, weil es über eine Fähigkeit verfügt, die gewöhnliche Objekte nicht haben: seine Eigenschaften mit anderen Objekten zu teilen.

In der ES6-Spezifikation ist es wie folgt definiert:

object that provides shared properties for other objects

Eigenschaftslesevorgang

Gehen Sie zum ursprünglichen Beispiel zurück und sehen Sie, wie Sie es mithilfe der prototypischen Vererbung implementieren Wiederverwendungszwecke.

var prototypeObj = {
  hello: function(){
    console.log( 'Hello, my name is '+ this.name  + '.');
  }
  // ...
}

var xiaoMing = {
  name : "xiaoMing",
  __proto__ : prototypeObj
}

var liLei = {
  name : "liLei",
  __proto__ :  prototypeObj
}

xiaoMing.hello(); // Hello, my name is xiaoMing.
liLei.hello();  // Hello, my name is liLei.

xiaoMing liLei Das Objekt hat nicht direkt das Hallo-Attribut (Methode), aber es kann das Attribut lesen (die Methode ausführen).

Stellen Sie sich ein Szenario vor, in dem Sie Mathe-Hausaufgaben machen und auf eine schwierige Frage stoßen, von der Sie nicht wissen, wie man sie löst. Und Sie haben einen guten Bruder, der sehr gut in Mathematik ist. Sie bitten ihn um Hilfe und lösen dieses Problem.

Es gibt kein Hallo-Attribut für das xiaoMing-Objekt, aber es hat einen guten Bruder, PrototypObj. Wenn bei Attributlesevorgängen das Hallo-Attribut in xiaoMing nicht gefunden wird, fragt es seinen Bruder „prototypObj“. Daher wird die Hello-Methode ausgeführt.

Prototypenkette

Es ist immer noch ein Beispiel für die Lösung mathematischer Probleme. Deine Mathefrage ist schwierig und dein Bruder hat keine Antwort. Er empfiehlt dir, sie einem anderen Klassenkameraden zu stellen. Auf diese Weise werden Sie nicht mehr fragen, bis Sie die Antwort haben oder niemand mehr da ist, der Sie fragen könnte. Es ist, als gäbe es eine unsichtbare Kette, die Sie mit Ihren Klassenkameraden verbindet.

In JS wird der Lesevorgang Schicht für Schicht über __proto__ verkettet, was als Prototypenkette bezeichnet wird.

var deepPrototypeObj = {
  hello: function(){
    console.log( 'Hello, my name is '+ this.name  + '.');
  }
  __proto__ : null
}

var prototypeObj = {
  __proto__ : deepPrototypeObj
}

var xiaoMing = {
  name : "xiaoMing",
  __proto__ : prototypeObj
}

var liLei = {
  name : "liLei",
  __proto__ :  prototypeObj
}

xiaoMing.hello(); // Hello, my name is xiaoMing.
liLei.hello();  // Hello, my name is liLei.

Implementierung der prototypischen Vererbung

Im obigen Beispiel wird die prototypische Vererbung durch direktes Ändern des Attributwerts __proto__ implementiert. Aber in der tatsächlichen Produktion besteht die

Alternative darin, die Methode Object.create() zu verwenden.

Durch den Aufruf der Methode Object.create() wird ein neues Objekt erstellt und das Prototypobjekt des Objekts als erster übergebener Parameter angegeben.

Ändern wir das obige Beispiel.

var prototypeObj = {
  hello: function(){
    console.log( 'Hello, my name is '+ this.name  + '.');
  }
  // ...
}

var xiaoMing = Object.create(prototypeObj);
var liLei = Object.create(prototypeObj);

xiaoMing.name = "xiaoMing";
liLei.name = "liLei";

xiaoMing.hello(); // Hello, my name is xiaoMing.
liLei.hello();  // Hello, my name is liLei.

Der Autor von You-Dont-Know-JS hat der Implementierung der prototypischen Vererbung einen sehr interessanten Namen gegeben: OLOO (objects-linked-to-other-objects). Der Vorteil dieser Implementierungsmethode besteht darin verwendet kein Klassenkonzept, sondern nur ein Objekt und ist daher sehr konsistent mit den Eigenschaften von JavaScript.

Weil es in JS keine Klassen gibt, sondern nur Objekte.

Leider gibt es zu viele Programmierer, die Klassen mögen, daher wurde das Klassenkonzept in ES6 hinzugefügt. Im nächsten Artikel geht es um das Implementierungsprinzip von Klassen in JS

Zusammenfassung

Klasse erstellt Objekte, um den Zweck der Wiederverwendung zu erreichen. Die Logik, auf der es basiert, besteht darin, dass zwei oder mehr Objekte ähnliche Strukturen und Funktionen haben. Eine Vorlage kann abstrahiert werden und mehrere ähnliche Objekte können entsprechend der Vorlage kopiert werden. Es ist, als würden Fahrradhersteller immer wieder dieselben Baupläne verwenden, um viele Fahrräder zu bauen. Durch die Verwendung der prototypischen Vererbung kann auch der Zweck der Wiederverwendung erreicht werden. Die Logik, auf der es basiert, besteht darin, dass zwei oder mehr Objekte über einige gemeinsame Attribute verfügen. Durch spezielle Prototypattribute können die öffentlichen Objekte mit dem Lesen (Schreiben) von gewöhnlichen Objekten verknüpft und wiederverwendet werden ) Regeln werden durchlaufen und durchsucht, um die Attribut-

-Freigabe

zu realisieren.

Das Obige ist ein detailliertes Verständnis der prototypischen Vererbung von JavaScript. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).

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