Eins. Zwei Prototypen
Viele Menschen wissen, dass JavaScript ein Prototyp -Vererbung ist. Jeder Konstruktor hat ein Prototyp -Mitglied, durch das die JavaScript -Vererbung schön sein kann.
Tatsächlich kann dieses Attribut allein die Vererbung von JavaScript nicht vervollständigen.
Ich werde nicht viel über den Prototyp sagen, den wir im Code verwenden. Sie können die Informationen überprüfen.
Ein weiteres unsichtbares Prototyp -Mitglied.
Jede Instanz hat ein Prototypattribut, das auf den Prototyp hinweist. Dieses Attribut kann nicht zugegriffen werden und kann natürlich nicht geändert werden, da dies die Grundlage für die Aufrechterhaltung der JavaScript -Vererbung ist.
Die Codekopie lautet wie folgt:
// Konstruktoranweisung
Funktion Guoyansi () {}
Funktion Guoyansiex () {}
// Prototyp -Vererbung
Guoyansiex.prototype = new Guoyansi ();
// ein Objekt erstellen
var g1 = new Guoyansiex ();
var g2 = new Guoyansiex ();
Die Objekte im obigen Code können durch die folgende Abbildung erklärt werden
2. Prototyp -Wartung
Eine Instanz, die von einem Konstruktor erzeugt wird, dessen Konstruktorattribut immer auf den Konstruktor weist. Wir werden denken, dass die Aussage vorerst korrekt ist.
Die Codekopie lautet wie folgt:
Funktion Guoyansi () {}
var obj1 = new Guoyansi ();
console.log (obj1.constructor === Guoyansi); // true
Tatsächlich hat der Konstruktor selbst nicht das Konstruktorattribut. Woher kommt dieses Attribut?
Die Antwort lautet: aus dem Prototyp.
Daher werden die folgenden Schlussfolgerungen gezogen
Die Codekopie lautet wie folgt: OBJ1.Constructor === Guoyansi.Prototype.Constructor === Guoyansi
Da wir den Konstruktor durch den Konstruktor finden können, können wir das obige Diagramm weiter verbessern.
Die Codekopie lautet wie folgt:
Funktion Guoyansiex () {}
Guoyansiex.prototype = new Guoyansi ();
console.log (Guoyansiex.Constructor === Guoyansiex) // False
Nach dem obigen Bild sollte das obige Ergebnis wahr sein, aber warum ist falsch?
Führen Sie nun eine Analyse durch.
Der Prototyp von Guoyansiex wurde durch die Instanz von Guoyansi umgeschrieben, sodass der Konstruktor im Prototyp von Guoyansie von Natur aus auch eine Instanz von Guoyansi ist.
Der Konstruktor in der Guoyansi -Instanz stammt von Guoyansi.Prototype. Guoyansi.Prototyp wurde jedoch nicht umgeschrieben.
So verweist der Konstruktor von Guoyansi.Prototyp auf Guoyansi (Konstruktor);
Basierend auf der obigen Analyse ziehen wir die folgenden Schlussfolgerungen
Die Codekopie lautet wie folgt: Guoyansiex.Constructor === Guoyansi.Constructor === Guoyansi;
Wenn die Richtlinienanforderungen des Konstruktors während des Entwicklungsprozesses sehr genau sind, kann die folgende Verarbeitung durchgeführt werden.
Die Codekopie lautet wie folgt:
/** Methode 1: **/
Funktion Guoyansi () {}
Funktion Guoyansiex () {}
Guoyansiex.prototype = new Guoyansi ();
Guoyansiex.Prototype.Constructor = Guoyansiex; // Konstruktorzeiger zurücksetzen.
Die Codekopie lautet wie folgt:
/**
Methode 2
**//
Funktion Guoyansi () {}
Funktion Guoyansiex () {
this.constructor = argumente.callee;
}
Guoyansiex.prototype = new Guoyansi ();
Die Codekopie lautet wie folgt:
/**
Methode 3
**//
Funktion Guoyansi () {}
Funktion Guoyansiex () {
this.constructor = Guoyansiex;
}
Guoyansiex.prototype = new Guoyansi ();
3. Wie nutzt ein unsichtbarer Prototyp?
Wir können die sichtbare Prototypkette bedienen, um unser Erbe zu vervollständigen, sodass wir diese unsichtbare Prototypkette nicht sehen und bedienen können. Was nutzt es?
Es gibt ein Merkmal in objektorientierter Vererbung: Ähnlichkeit. Unterklassen haben Ähnlichkeiten mit übergeordneten Klassen. Daher können Sie in Unterklassen nicht Löschen verwenden, um Mitglieder zu löschen, die von übergeordneten Klassen geerbt wurden. Das heißt, Unterklassen müssen die Eigenschaften von Elternklassen haben.
Um diese Funktion beizubehalten, generiert JavaScript im Objekt eine unsichtbare Prototyp -Eigenschaft und erlaubt dem Benutzer nicht, darauf zugreifen zu können. Auf diese Weise kann der Benutzer den Konstruktor für jeden Zweck ändern.
Es wird nicht die Eigenschaften der Kinderklasse mit der Elternklasse zerstören.
Kurz gesagt: Interne Prototypen werden durch den Prototyp -Vererbungsmechanismus von JavaScript benötigt, während externe Prototypen von den Benutzern die Implementierung der Vererbung erforderlich sind.
4. __Proto__ im Firefox -Motorspidermonkey
Immer noch dieser Code.
Die Codekopie lautet wie folgt:
Funktion Guoyansi () {}
Guoyansi.Prototype.age = 24;
Funktion Guoyansiex () {}
var obj1 = new Guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.Prototype.Constructor = Guoyansiex; // Konstruktorzeiger zurücksetzen.
var obj2 = new Guoyansiex ();
Ich möchte jetzt auf das Alter der Eigenschaften des Prototyps der übergeordneten Klasse Guoyansi ab OBJ zugreifen.
Das ist die Idee.
Schritt 1: OBJ2 ====> obj2.Constructor.Prototyp
Teil 2: obj2.Constructor.Prototype ===> Guoyansiex.Prototyp;
Teil 3: Guoyansiex.Prototyp ===> OBJ1;
Teil 4: OBJ1.Constructor ====> Guoyansi
Teil 5: Guoyansi.Prototype.age
Schreiben Sie es so: console.log (obj2.constructor.prototype.constructor.prototype.age) // 24;
Das Endergebnis ist 24.
Das Endergebnis ist 24. Es kann normal ausgeführt werden, aber in vielen Büchern heißt es, dass der Prototyp in der übergeordneten Klasse nach dem Änderung des Konstruktors den Prototyp nicht finden kann. Ich weiß nicht, was los ist.
Genug eines präziseren Attributs in Firefox._Proto_
Standardmäßig fügt Spidermonkey ein Attribut namens _proto_ zu jedem erstellten Objekt hinzu, das dem vom Konstruktor verwendeten Prototyp verweist.
Tatsächlich ist es die oben erwähnte unsichtbare Prototypkette, aber es handelt sich nur um eine verkleidete Offenlegung an diesem Ort.
Sie können auf diese Weise auf das Alter zugreifen
console.log (obj2 .__ proto __.__ Proto __. Alter); // 24
Dies greift tatsächlich erfolgreich auf das Prototyp -Attribut der übergeordneten Klasse zu, aber dieses Attribut ist nur für Firefox anwendbar, und es werden Fehler in anderen Browsern auftreten.
In E5 wird Objekt auf Object.getPrototypeof () erweitert, und Sie können auf alle Prototypen der Elternklassen zugreifen.
Die Codekopie lautet wie folgt:
Funktion Guoyansi () {}
Guoyansi.Prototype.age = 24;
Funktion Guoyansiex () {}
var obj1 = new Guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.Prototype.Constructor = Guoyansiex; // Konstruktorzeiger zurücksetzen.
var obj2 = new Guoyansiex ();
var proto = Object.getPrototypeof (obj2);
while (proto) {
console.log (proto.constructor);
proto = object.getPrototypeof (proto);
}
console.log ("Objektprototyp"+Proto);
Das Ergebnis ist: Guoyansiex
Guoyansi
Objekt
Prototypennull für Objekt
Ich persönlich denke, diese sollten als eine der Essenzen von objektorientiertem JavaScript angesehen werden. Bitte beachten Sie es selbst und verwenden Sie es in Ihrem eigenen Projekt entsprechend Ihren Anforderungen.