Heim > Web-Frontend > js-Tutorial > Hauptteil

Detaillierte Erläuterung des Funktionsprinzips und Beispiele für prototypische Javascript-Vererbung_Javascript-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:06:07
Original
1500 Leute haben es durchsucht

Zuerst werde ich Ihnen als Referenz ein Beispiel für die prototypische Vererbung von JS mitteilen. Der spezifische Inhalt ist wie folgt

1. JS-Prototypvererbung

<!DOCTYPE html>
<html>

<head>
 <meta charset="UTF-8">
 <title>JS原型继承</title>
</head>

<body>
 <!--原型继承-->
 <script type="text/javascript">
 //clone()函数用来创建新的类Person对象
 var clone = function(obj) {
  var _f = function() {};
  //这句是原型式继承最核心的地方,函数的原型对象为对象字面量
  _f.prototype = obj;
  return new _f;
 }

 //先声明一个对象字面量
 var Animal = {
   somthing: 'apple',
   eat: function() {
    console.log("eat " + this.somthing);
   }
  }
  //不需要定义一个Person的子类,只要执行一次克隆即可
 var Cat = clone(Animal);
 //可以直接获得Person提供的默认值,也可以添加或者修改属性和方法
 console.log(Cat.eat());
 Cat.somthing = 'orange';
 console.log(Cat.eat());

 //声明子类,执行一次克隆即可
 var Someone = clone(Cat);
 </script>
</body>

</html>
Nach dem Login kopieren

2. Wie die prototypische Vererbung von JavaScript funktioniert

Es ist bekannt, dass JavaScript die prototypische Vererbung verwendet, aber da es standardmäßig nur eine Implementierungsinstanz bereitstellt, nämlich den neuen Operator, ist die Erklärung immer verwirrend. Was sollte ich als nächstes erklären und wie man es genau verwendet? es in JavaScript.

Definition der prototypischen Vererbung

Wenn Sie die Erklärung zur prototypischen Vererbung von JS lesen, werden Sie häufig den folgenden Text sehen:

Bei der Suche nach einer Eigenschaft eines Objekts durchläuft JavaScript die Prototypenkette, bis es eine Eigenschaft mit einem bestimmten Namen findet. ——Von JavaScript Secret Garden
Die meisten Implementierungen von JavaScript verwenden das Attribut __proto__, um die Prototypenkette eines Objekts darzustellen. In diesem Artikel werden wir sehen, was der Unterschied zwischen __proto__ und Prototyp ist.

Hinweis: __proto__ ist eine informelle Verwendung, die nicht in Ihrem Code vorkommen sollte. Sie wird hier nur verwendet, um zu erklären, wie die prototypische Vererbung von JavaScript funktioniert.

Der folgende Code zeigt, wie die JS-Engine nach Attributen sucht:

function getProperty(obj, prop) { 
 if (obj.hasOwnProperty(prop)) 
 return obj[prop] 
 
 else if (obj.__proto__ !== null) 
 return getProperty(obj.__proto__, prop) 
 
 else 
 return undefined 
} 
Nach dem Login kopieren

Nehmen wir ein allgemeines Beispiel: Ein zweidimensionaler Punkt mit zweidimensionalen Koordinaten x y hat auch eine Druckmethode.

Unter Verwendung der zuvor erwähnten Definition der prototypischen Vererbung erstellen wir einen Objektpunkt mit drei Eigenschaften: x, y und print. Um einen neuen zweidimensionalen Punkt zu erstellen, müssen wir ein neues Objekt erstellen und dessen __proto__-Attribut auf Point:

zeigen lassen
var Point = { 
 x: 0, 
 y: 0, 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = {x: 10, y: 20, __proto__: Point}; 
p.print(); // 10 20 
Nach dem Login kopieren

Die seltsame prototypische Vererbung von JavaScript

Das Verwirrende ist, dass jeder, der prototypische Vererbung lehrt, keinen solchen Code, sondern den folgenden Code gibt:

function Point(x, y) { 
 this.x = x; 
 this.y = y; 
} 
Point.prototype = { 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = new Point(10, 20); 
p.print(); // 10 20 
Nach dem Login kopieren

Das ist anders als versprochen. Hier wird Point zu einer Funktion, und dann gibt es eine Prototyp-Eigenschaft und einen neuen Operator. Was ist mit diesem Kerl los?

So funktioniert der neue Operator

Der Schöpfer Brendan Eich wollte, dass JS traditionellen objektorientierten Programmiersprachen wie Java und C++ ähnelt. In diesen Sprachen verwenden wir den new-Operator, um ein neues Objekt für eine Klasse zu instanziieren. Also schrieb er einen neuen Operator in JS.

C++ verfügt über das Konzept eines Konstruktors, der zum Initialisieren von Instanzeigenschaften verwendet wird, sodass der neue Operator auf Funktionen abzielen muss.
Wir müssen die Methoden des Objekts an einem Ort unterbringen, und da wir eine Prototypsprache verwenden, platzieren wir sie im Prototypattribut der Funktion.
Der neue Operator akzeptiert eine Funktion F und ihre Argumente: new F(arguments...). Dieser Vorgang ist in drei Schritte unterteilt:

Erstellen Sie eine Instanz der Klasse. In diesem Schritt wird das __proto__-Attribut eines leeren Objekts auf F.prototype gesetzt.
Initialisieren Sie die Instanz. Funktion F wird mit übergebenen Argumenten aufgerufen und das Schlüsselwort this wird auf die Instanz gesetzt.
Instanz zurückgeben.
Da wir nun wissen, wie New funktioniert, können wir es mit JS-Code implementieren:

function New (f) { 
 var n = { '__proto__': f.prototype }; /*第一步*/ 
 return function () { 
 f.apply(n, arguments);  /*第二步*/ 
 return n;    /*第三步*/ 
 }; 
} 
Nach dem Login kopieren

Ein kleines Beispiel, um seinen Arbeitsstatus zu betrachten:

function Point(x, y) { 
 this.x = x; 
 this.y = y; 
} 
Point.prototype = { 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p1 = new Point(10, 20); 
p1.print(); // 10 20 
console.log(p1 instanceof Point); // true 
 
var p2 = New (Point)(10, 20); 
p2.print(); // 10 20 
console.log(p2 instanceof Point); // true 
Nach dem Login kopieren

Echte prototypische Vererbung in JavaScript

Die ECMA-Spezifikation von JS erlaubt uns nur die Verwendung des neuen Operators für die prototypische Vererbung. Aber der große Meister Douglas Crockford entdeckte einen Weg, Neues zu nutzen, um eine echte prototypische Vererbung zu erreichen! Er hat die Object.create-Funktion wie folgt geschrieben:

Object.create = function (parent) { 
 function F() {} 
 F.prototype = parent; 
 return new F(); 
}; 
Nach dem Login kopieren

Das sieht seltsam aus, ist aber ziemlich nett: Es erstellt ein neues Objekt und setzt seinen Prototyp auf den gewünschten Wert. Wenn wir die Verwendung von __proto__ zulassen, können wir auch so schreiben:

Object.create = function (parent) { 
 return { '__proto__': parent }; 
}; 
Nach dem Login kopieren

Der folgende Code ermöglicht es unserem Point, eine echte prototypische Vererbung zu übernehmen:

var Point = { 
 x: 0, 
 y: 0, 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = Object.create(Point); 
p.x = 10; 
p.y = 20; 
p.print(); // 10 20 
Nach dem Login kopieren

Fazit

Wir haben gelernt, was JS-Prototypvererbung ist und wie JS sie auf bestimmte Weise implementiert. Die Verwendung echter prototypischer Vererbung (wie Object.create und __proto__) hat jedoch immer noch die folgenden Nachteile:

Schlechte Standardisierung: __proto__ ist keine Standardverwendung oder sogar eine veraltete Verwendung. Gleichzeitig unterscheiden sich auch das ursprüngliche Object.create und die von Dao Ye geschriebene Originalversion.
Schlechte Optimierung: Unabhängig davon, ob es sich um natives oder angepasstes Object.create handelt, ist seine Leistung weitaus weniger optimiert als die neue, und ersteres ist bis zu zehnmal langsamer als letzteres.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein.

Verwandte Etiketten:
js
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