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