In einer typischen objektorientierten Sprache wie Java gibt es das Konzept der Klasse. Klasse ist die Vorlage eines Objekts und ein Objekt ist eine Instanz einer Klasse. Im JavaScript -Sprachsystem gibt es jedoch kein Konzept der Klasse. JavaScript basiert nicht auf "Klasse", sondern wird durch Konstruktoren und Prototypketten implementiert. ES6 bietet jedoch eine Schreibmethode, die näher an traditionellen Sprachen liegt und das Konzept der Klasse (Klasse) als Objektvorlage einführt. Durch das Schlüsselwort der Klasse können Sie eine Klasse definieren. Grundsätzlich kann die Klasse von ES6 nur als Syntaxzucker angesehen werden. Die meisten seiner Funktionen können durch ES5 erreicht werden. Die neue Klassenschreibmethode macht das Prototyp-Objekt nur klarer und eher der objektorientierten Programmiersyntax.
Nach meiner Gewohnheit werde ich das Artikelverzeichnis geben, bevor ich es schreibe.
Der folgende Inhalt wird in die folgenden Unterabschnitte unterteilt:
1. Eine kurze Einführung in Konstrukteure
2. Nachteile von Konstruktoren
3. Die Rolle des Prototyp -Attributs
4. Prototyp -Kette
5.Constructor -Attribut
5.1: Die Rolle des Konstruktorattributs
6. Instanz des Bedieners
1. Eine kurze Einführung in Konstrukteure
In meinem Artikel über die enge Beziehung zwischen Konstruktoren und neuen Befehlen in JavaScript werden das Konzept und die Eigenschaften von Konstruktoren, die Prinzipien und die Verwendung neuer Befehle usw. ausführlich vorgestellt. Wenn Sie mit Konstruktoren nicht vertraut sind, können Sie sie sorgfältig genießen. Hier ist eine einfache Bewertung.
Der sogenannte Konstruktor ist eine Funktion, die eine Vorlage zum Generieren eines Objekts bereitstellt und die Grundstruktur des Objekts beschreibt. Ein Konstruktor kann mehrere Objekte mit jeweils gleicher Struktur erzeugen. Im Allgemeinen ist ein Konstruktor eine Vorlage für ein Objekt, und ein Objekt ist eine Instanz eines Konstruktors.
Die Eigenschaften des Konstruktors sind:
A: Der erste Buchstabe des Funktionsnamens des Konstruktors muss aktiviert werden.
B: Verwenden Sie dieses Objekt intern, um auf die zu generierende Objektinstanz zu verweisen.
C: Verwenden Sie den neuen Bediener, um den Konstruktor aufzurufen und die Objektinstanz zurückzugeben.
Lassen Sie uns das einfachste Beispiel sehen.
Funktion person () {this.name = 'keith';} var boy = new Person (); console.log (boy.name); // 'Keith'2. Nachteile von Konstruktoren
Alle Instanzobjekte können Eigenschaften und Methoden im Konstruktor erben. Immobilien können jedoch nicht zwischen denselben Objektinstanzen geteilt werden.
Funktionsperson (Name, Höhe) {this.name = name; this.height = Höhe; this.hobby = function () {return 'Filme anschauen';}} var boy = new Person ('Keith', 180); var girl = neue Person ('Rascal', 153); console.log (boy.name); // 'Keith' console.log (Mädchen.name); // 'rascal' console.log (boy.hobby === Mädchen.Hobby); //FALSCHIm obigen Code generiert eine Konstruktor -Person zwei Objektinstanzen Jungen und Mädchen und verfügt über zwei Eigenschaften und eine Methode. Ihre Hobby -Methode ist jedoch anders. Das heißt, wenn Sie mit Neuen den Konstruktor anrufen, um eine Objektinstanz zurückzugeben, wird eine Hobby -Methode erstellt. Dies ist weder notwendig noch eine Verschwendung von Ressourcen, da alle Hobby -Methoden kindliches Verhalten sind und von zwei Objektinstanzen vollständig geteilt werden können.
Der Nachteil von Konstruktoren besteht daher darin, dass Eigenschaften oder Methoden nicht zwischen Objektinstanzen desselben Konstruktors geteilt werden können.
3. Die Rolle des Prototyp -Attributs
Um den Nachteil zu lösen, dass JS nicht in der Lage ist, Eigenschaften zwischen Objektinstanzen von Konstruktoren zu teilen, liefert JS Prototypattribute.
Jeder Datentyp in JS ist ein Objekt (außer Null und Undefined), und jedes Objekt erbt von einem anderen Objekt. Letzteres wird als "Prototyp" -Objekt bezeichnet, mit Ausnahme von Null, das kein eigenes Prototyp -Objekt hat.
Alle Eigenschaften und Methoden im Prototypobjekt werden von der Objektinstanz gemeinsam genutzt.
Wenn eine Objektinstanz über einen Konstruktor erzeugt wird, wird der Prototyp der Objektinstanz auf die Prototyp -Eigenschaft des Konstruktors hingewiesen. Jeder Konstruktor hat ein Prototypattribut, das das Prototypobjekt der Objektinstanz ist.
Funktionsperson (Name, Höhe) {this.name = name; this.height = Höhe; } Person.Prototype.hobby = function () {return 'Filme ansehen'; } var boy = new Person ('Keith', 180); var girl = neue Person ('Rascal', 153); console.log (boy.name); // 'Keith' console.log (Mädchen.name); // 'rascal' console.log (boy.hobby === Mädchen.Hobby); //WAHRWenn im obigen Code die Hobby -Methode auf das Prototyp -Objekt platziert ist, teilen beide Instanzobjekte dieselbe Methode. Ich hoffe, jeder kann verstehen, dass für Konstruktoren Prototyp eine Eigenschaft als Konstruktor ist. Für Objektinstanzen ist Prototyp ein Prototypobjekt von Objektinstanzen. Daher ist Prototyp eine Eigenschaft und ein Objekt.
Prototypobjekte sind keine Eigenschaften von Objektinstanzen. Die Attribute einer Objektinstanz sind Attribute, die aus der Definition des Konstruktors geerbt wurden, da sich im Konstruktor ein Schlüsselwort befindet, um auf die zu generierende Objektinstanz zu verweisen. Die Eigenschaften einer Objektinstanz sind tatsächlich vom Konstruktor intern definierte Attribute. Solange die Eigenschaften und Methoden des Prototyp -Objekts geändert werden, werden die Änderungen sofort in allen Objektinstanzen widerspiegelt.
Person.Prototype.Hobby = function () {return 'Swimming'; } console.log (boy.hobby === Mädchen.Hobby); // True Console.log (boy.hobby ()); // 'Swimming'console.log (Girl.Hobby ()); //'Baden'Im obigen Code haben sich beide Objektinstanzen nach der Änderung der Hobby -Methode des Prototyp -Objekts geändert. Dies liegt daran, dass Objektinstanzen tatsächlich keine Hobby -Methoden haben. Sie sind alle Hobby -Methoden, die Prototypobjekte lesen. Das heißt, wenn eine Objektinstanz nicht über die Eigenschaft und Methode verfügt, wird im Prototyp -Objekt gesucht. Wenn das Instanzobjekt selbst eine bestimmte Eigenschaft oder Methode hat, wird es nicht im Prototyp -Objekt durchsucht.
boy.hobby = function () {return 'basketball spielen'; } console.log (boy.hobby ()); // 'Basketball spielen' console.log (girl.hobby ()); //'Baden'Wenn die Hobby -Methode der Boy -Objektinstanz geändert wird, wird im obigen Code die Hobby -Methode des Prototypenobjekts nicht vererbt. Mädchen erben jedoch immer noch die Methode des Prototyp -Objekts.
Zusammenfassen:
A: Die Funktion eines Prototyp -Objekts besteht darin, die Eigenschaften und Methoden zu definieren, die von allen Objektinstanzen geteilt werden.
B: Prototyp für Konstruktoren ist es eine Eigenschaft; Für Objektinstanzen ist es ein Prototypobjekt.
4. Prototyp -Ketten
Die Eigenschaften und Methoden eines Objekts können in sich oder in seinem Prototypobjekt definiert werden. Da das Prototypobjekt selbst auch ein Objekt für Objektinstanzen ist und auch einen eigenen Prototyp hat, wird eine Prototypkette gebildet. Zum Beispiel ist Objekt A der Prototyp von Objekt B, Objekt B ist der Prototyp von Objekt C und so weiter. Die Oberseite des Prototyps aller Objekte ist das Objekt.Prototyp, dh das von der Prototyp -Eigenschaft des Objektkonstruktors angezeigte Objekt.
Natürlich hat das Object.Prototyp -Objekt auch ein eigenes Prototyp -Objekt, dh ein Null -Objekt ohne Attribute und Methoden, und das Null -Objekt hat keinen eigenen Prototyp.
1 console.log (Object.getPrototypeof (Object.Prototype)); // null
2 console.log (person.Prototype.riprototypeof (boy)) // true
Die Eigenschaften von Prototypketten sind:
A: Beim Lesen einer bestimmten Eigenschaft eines Objekts sucht die JavaScript -Engine zuerst nach der Eigenschaft des Objekts selbst. Wenn es nicht gefunden werden kann, geht es zu seinem Prototyp. Wenn es immer noch nicht gefunden werden kann, geht es zum Prototyp des Prototyps. Wenn das Object.Prototyp auf der oberen Ebene noch nicht gefunden wird, wird undefiniert zurückgegeben.
B: Wenn das Objekt selbst und sein Prototyp ein gleichnamiges Attribut definieren, werden zuerst die Attribute des Objekts selbst gelesen, was als "überschreibend" bezeichnet wird.
C: Die Suche nach einem bestimmten Attribut im Prototyp -Kettenebene nach oben hat einen Einfluss auf die Leistung. Je höher die Ebene des von Ihnen gesuchten Prototypobjekts, desto größer ist die Auswirkungen auf die Leistung. Wenn Sie nach einer nicht existierenden Eigenschaft suchen, durchquert dies die gesamte Prototypkette.
Es kann unklar sein, das Konzept zu betrachten, nehmen wir ein Beispiel. Aber es ist wirklich wichtig, das Konzept zu verstehen.
var arr = [1,2,3]; console.log (arr.length); //3console.log (arr.ValueOf ()) // [1,2,3] console.log (arr.join ('|') // 1 | 2 | 3Im obigen Code wird ein Array -ARR mit drei Elementen im Array definiert. Wir haben dem Array keine Attribute oder Methoden hinzugefügt, aber beim Aufrufen von Länge, Join () und ValueOF () keinen Fehler gemeldet.
Das Längenattribut wird von Array.Prototyp geerbt und gehört zu einer Eigenschaft auf dem Prototypobjekt. Die Join -Methode wird auch von Array.Prototyp geerbt und gehört zu einer Methode des Prototyps -Objekts. Diese beiden Methoden werden von allen Arrays geteilt. Wenn das Instanzobjekt kein Längenattribut vorhanden ist, wird das Prototyp -Objekt durchsucht.
Die ValueOF -Methode wird von Object.Prototype vererbt. Zunächst hat das Array des ARR -Arrays keine Wertvereigerung. Anschließend stellte ich fest, dass es im Array.Prototyp -Objekt keine Wertmethode gibt. Schließlich schauen Sie das Objekt nach.
Schauen wir uns die Eigenschaften und Methoden des Array.Prototypen -Objekts und des Object.Prototyp -Objekts an.
console.log (Object.getownPropertynames (array.prototype)) // ["Länge", "Tosource", "Tostring", "Tolocalestring", "," Reverse "," Sort "," Push "," Pop "," Shift "," Unshifting "," Indect ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", "," wurde er "," wurde " "Karte", "Filter", "Reduktoright", "einige", "jeder", "find", "findIndex", "copywithin", "fill", "Einträge", "Keys", "Keys", "Werte", "Include", "Constructor", "$ set", "$ entfernen". "ToString", "Tolocalestring", "Valueof", "Watch", "Unwatch", "HasownProperty", "
Ich glaube, wenn Sie dies sehen, haben Sie immer noch ein sehr geringes Verständnis des Prototyps. Das ist normal. Schließlich ist es ein wichtigeres und abstrakteres Konzept in JS. Es ist unmöglich, es so schnell zu meistern. Wenn Sie noch ein paar Artikel gegessen haben, können Sie die Essenz beherrschen. In gewisser Weise gibt es ein lebendiges Beispiel, das auch ein Problem sein kann, dem jeder begegnen wird. Sie können sich JS Constructor und Prototyp -Objekte ansehen.
5.Constructor -Attribut
Das Prototyp -Objekt verfügt über ein Konstruktorattribut, das auf die Konstruktorfunktion hinweist, in der sich das Prototyp -Objekt standardmäßig befindet.
Funktion a () {}; console.log (A.Prototype.Constructor === a) // trueEs ist zu beachten, dass Prototyp die Eigenschaft des Konstruktors und Konstruktor das Objekt ist, auf das die Prototyp -Eigenschaft des Konstruktors, dh die Eigenschaft des Prototypsobjekts, hingewiesen wird. Achten Sie darauf, nicht zu verwirren.
console.log (A. HasownProperty ('Prototyp')); // True Console.log (A.Prototype.hasownProperty ('Constructor')); //WAHRDa das Konstruktorattribut auf dem Prototypobjekt definiert ist, kann es von allen Instanzobjekten vererbt werden.
Funktion a () {}; var a = new a (); console.log (a.constructor); //A()console.log(A.Constructor====a.Prototype.Constructor);//trueIm obigen Code ist A ein Instanzobjekt von Konstruktor A, aber A selbst hat kein Konstruktorattribut, das tatsächlich die Prototypkette liest.
A.Prototype.Constructor -Eigenschaft.
5.1: Die Rolle des Konstruktorattributs
A: Bestimmen Sie, zu welcher Konstruktorfunktion das Prototyp -Objekt ist, zu dem gehört wird
Funktion a () {}; var a = new a (); console.log (a.constructor === a) // true console.log (a.constructor === array) // falseDer obige Code bedeutet, dass die Verwendung der Konstruktoreigenschaft festgestellt wird, dass die Konstruktorfunktion des Instanzobjekts a a und nicht ein Array ist.
B: Erstellen Sie eine andere Instanz aus der Instanz
Funktion a () {}; var a = new a (); var b = new a.constructor (); console.log (b Instanz von a); //WAHRIm obigen Code ist A ein Instanzobjekt des Konstruktors A, und der Konstruktor kann indirekt von A.Constructor genannt werden.
C: Es ist möglich, seinen eigenen Konstruktor anzurufen
A.Prototype.hello = function () {return new this.constructor (); }D: Bietet ein Muster der Erben eines anderen Konstruktors von einem Konstruktor
Funktion fater () {} function Son () {Son.Height.Constructor.call (this); } Son.Height = new father ();Im obigen Code sind Vater und Sohn beide Konstruktoren. Der Vater in diesem Inside -Sohn zu rufen, wird die Wirkung eines Sohnes erben, der Vater erbt.
E: Da das Konstruktorattribut eine Beziehung zwischen einem Prototyp -Objekt und einem Konstruktor ist, müssen Sie beim Ändern des Prototyp -Objekts auf das Problem des Konstruktors achten.
Es gibt zwei Lösungen: Zeigen Sie entweder das Konstruktorattribut auf die ursprüngliche Konstruktorfunktion oder fügen Sie dem Prototyp -Objekt einfach Eigenschaften und Methoden hinzu, um eine Instanzverzerrung zu vermeiden.
6. Instanz des Bedieners
Der Instanz des Operators gibt einen booleschen Wert zurück, der angibt, ob das angegebene Objekt eine Instanz eines Konstruktors ist.
Funktion a () {}; var a = new a (); console.log (a Instanz von a); //WAHRDa InstanceOF für Objekte in der gesamten Prototypkette gültig ist, kann dasselbe Instanzobjekt für mehrere Konstruktoren true.
Funktion a () {}; var a = new a (); console.log (eine Instanz von a); //Trueconsole.log(A -Instanz des Objekts); //WAHRBeachten Sie, dass Instanzobjekte nur für komplexe Datentypen (Arrays, Objekte usw.) verwendet werden können und nicht für einfache Datentypen (Boolesche Werte, Zahlen, Zeichenfolgen usw.) verwendet werden können.
var x = [1]; var o = {}; var b = true; var c = 'String'; console.log (x Instanz von Array); //trueconsole.log(o Instanceof Object); // true console.log (b Instanz des Booleschen); //falseconsole.log(cinstanceof String); //FALSCHAußerdem sind weder Null noch undefined Objekte, daher gibt es immer falsch zurück.
console.log (null Instanceof Objekt); // false console.log (undefined Instance of Object); //FALSCH
Mit dem Instanzoperator können Sie auch das Problem des Vergessens lösen, einen neuen Befehl hinzuzufügen, wenn Sie den Konstruktor aufrufen.
Funktion Keith (Name, Höhe) {if (! Diese Instanz von Keith) {return New Keith (Name, Höhe); } this.name = name; this.height = Höhe;}Im obigen Code wird der Instanzoperator verwendet, um zu bestimmen, ob das Schlüsselwort im Funktionsgremium auf eine Instanz des Konstruktors Keith zeigt. Wenn nicht, bedeutet dies, dass der neue Befehl vergessen wird. Zu diesem Zeitpunkt gibt der Konstruktor eine Objektinstanz zurück, um unerwartete Ergebnisse zu vermeiden.
Aus Platzbeschränkungen werde ich es vorerst hier vorstellen.
In meinem nächsten Anteil werde ich über native Methoden von Prototyp -Objekten wie Object.getPrototypeof (), Object.SetPrototypeof () () usw. sprechen und einen Vergleich von Methoden zum Erhalten natives Objekt einführen.
Das obige ist die detaillierte Erläuterung des Prototyps -Attributs (empfohlen) in JavaScript, das Ihnen vom Editor vorgestellt wurde. Ich hoffe, es wird Ihnen hilfreich sein.