Heim  >  Artikel  >  Web-Frontend  >  Mehrere Details zur Vererbung der JS-Prototypkette. Blog-Kategorie: JavaScript

Mehrere Details zur Vererbung der JS-Prototypkette. Blog-Kategorie: JavaScript

巴扎黑
巴扎黑Original
2016-11-25 10:02:541277Durchsuche

1. So implementieren Sie nur den erbenden Prototyp

Sehen Sie sich zunächst den folgenden Code an:

Js-Code

Funktion A(){

this .name ="Li Keke";

this.age=21;

} ) }

function B(){}

B.prototype =new A;//B erbt A

var cc=new B ;

cc.eat();//Ich kann essen

cc.name;//"Li Keke"

Was wir sehen können ist, dass A alle Attribute von B erbt. Was sollen wir also tun, wenn wir nur möchten, dass B das A.prototype-Attribut erbt und dies nicht tut? Möchten Sie den Namen und das Alter auf A und viele nutzlose Dinge?

Jemand hätte vielleicht gesagt, würde es nicht wie folgt gemacht werden:

Js code

B.prototype=A.prototype;

var cc =new B;

cc.eat();//Ich kann essen

cc.name;//undefiniert

Yo, es scheint perfekt? Schauen Sie sich weiterhin

Js-Code

B.prototype.fuck=function(){console.log("I fuck you!")}

var cc=new an B ,dd=new A;

cc.fuck();//Ich ficke dich

dd.fuck();//Ich ficke dich! / Oh mein Gott, wie kommt es, dass beide das Fluchen gelernt haben

//Wenn sich der Prototyp der Unterklasse B ändert, wirkt sich das auch auf den Prototyp von A aus (und umgekehrt natürlich auch). Sehr einfach, weil wir A.prototype auf den Prototyp von B zeigen lassen

Lösung:

Konstruieren Sie eine Funktion, die ein leeres Objekt erstellt, und lassen Sie den Prototyp des leeren Objekts auf das übergeordnete Objekt zeigen Schließlich wird eine Instanz des Objekts zurückgegeben. Der Code lautet wie folgt:

Js-Code

Object.createPro=function(pro){

function F() {}

F .prototype=pro;

return new F;

Wir können es testen:

Js-Code

function A (){

this.name="Li Keke"

this.age=21;

A.prototype.eat=function (){ console.log("I can eat") }

function B(){}

B.prototype=Object.createPro(A. Prototyp);//B erbt nur das Prototypattribut von A

var cc=new B;

cc.eat();//Ich kann essen

cc.name; //

B.prototype.fuck=function(){console.log("I fuck you!")}//Wir ändern jetzt den Prototyp von B

var dd=new A;

dd.fuck();//Report TypeError

//Gibt an, dass die Änderung von B.prototype keine Auswirkungen auf Attribute von A

Aber das ist zu mühsam. Nun, ES5 hilft uns, dieses Problem zu lösen. Wir können direkt die statische Methode create() verwenden, die mit Object:

Js-Code

geliefert wird function A(){

this.name="Li Keke";

this.age=21;

A.prototype.eat =function(){ console.log(" I can eat") }

function B(){}

B.prototype=Object.create(A.prototype);//Only den Prototyp von A erben

Während der Vererbung können Sie B auch einige eindeutige Attribute wie folgt hinzufügen:

Js-Code

Funktion A(){

this .name="Li Keke";

this.age=21;

}

A.prototype.eat=function(){ console.log("Ich kann eat") }

function B(){}

B.prototype=Object.create(A.prototype,{

p: { value: 42, beschreibbar: false, aufzählbar: true }// Füge eine Eigenschaft p hinzu, die nicht beschreibbar ist, aber aufgezählt werden kann

var pp=new B; p;//42

pp.name;//undefiniert

pp.eat();//Ich kann essen

pp.p=666;

pp.p ;//42 (nicht beschreibbar)

Der zweite Parameter ist Object.defineproperties() sehr ähnlich, wo Sie mehrere Eigenschaften konfigurieren und einige spezielle Berechtigungs-Tags vergeben können

Wenn Sie übergeben möchten, ist es dieser Methode natürlich auch möglich, alle Eigenschaften von A zu erben, wie im folgenden

Js-Code

B.prototype=Object.create(new A) ;

Es ist zu beachten, dass die Kompatibilität der Methode „create“ nur mit Browsern möglich ist, die mit ES5 kompatibel sind, oder wir können eine selbst simulieren, genau wie die Methode „Object.createPro“ oben

2. Bezüglich der Frage des Konstruktorzeigens und der Aufzählbarkeit des Konstruktors

In der ersten Frage haben wir die Methode Object.create verwendet, um die Vererbung zwischen verschiedenen Klassen zu implementieren. Dabei gibt es jedoch ein Problem wie folgt:

Js-Code

Funktion A(){

this.name="Li Keke";

this.age=21;

A.prototype function(){ console.log("I can eat") }

function B(){}

B.prototype=Object.create(A.prototype); 🎜>

var cc=new B;

cc.constructor;//A  (Hier haben wir erwartet, dass der Wert B ist, aber es wurde tatsächlich A)

Also Wie kann das obige Problem gelöst werden?

Js-Code

//Das einfachste, was wir uns vorstellen können, ist, das Konstruktorattribut manuell festzulegen, wie folgt:

B.prototype.constructor=B

Dann tritt das Problem erneut auf. Schauen Sie sich bitte Folgendes an:

Js-Code

B.prototype.propertyIsEnumerable("constructor");//true (die von uns festgelegte Konstruktoreigenschaft ist aufzählbar)

Natürlich wollen wir nicht, dass das der Fall ist, also was sollen wir tun?

Js-Code

//Verwenden Sie die Methode Object.defineProperty oder Object.defineProperties, um die Aufzählung des Konstruktors auf false zu setzen

Object.defineProperty(B.prototype," Konstruktor",{

value:B,

enumerable:false//Not enumerable

});

cc.constructor;//B

B.prototype.propertyIsEnumerable("constructor");//false

Bei der Verwendung von Objektliteralen zum Umschreiben des Prototyps einer Klasse gibt es ein ähnliches Problem, wie das folgende

Js-Code

function C(){}

C.prototype={}

var pp=new C

pp.constructor;/ / Objekt (wir erwarten C)

C.prototype.constructor=C;

C.prototype.propertyIsEnumerable("constructor");//true (auch aufzählbar)

//Sie können es hier auch mit der oben genannten Methode lösen

Natürlich gibt es eine andere Möglichkeit, es nicht neu zu schreiben, sondern einfach Attribute hinzuzufügen, wie folgt:

Js-Code

function D(){}

D.prototype.x=1;

var gg=new D;

gg. Konstruktor; //D

D.prototype.propertyIsEnumerable("constructor");//false

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