Der Inhalt dieses Artikels ist eine (detaillierte) Analyse einer Interviewfrage zur JavaScript-Prototypenkette. Ich hoffe, dass er für Sie hilfreich ist.
Vor den Basics sind alle Fähigkeiten umsonst.
Erfordert das Schreiben der Ausgabe der Konsole.
function Parent() { this.a = 1; this.b = [1, 2, this.a]; this.c = { demo: 5 }; this.show = function () { console.log(this.a , this.b , this.c.demo ); } } function Child() { this.a = 2; this.change = function () { this.b.push(this.a); this.a = this.b.length; this.c.demo = this.a++; } } Child.prototype = new Parent(); var parent = new Parent(); var child1 = new Child(); var child2 = new Child(); child1.a = 11; child2.a = 12; parent.show(); child1.show(); child2.show(); child1.change(); child2.change(); parent.show(); child1.show(); child2.show();
dies verweist auf die
Prototyp-Maschine-Prototyp-Kette
Vererbung der Klasse
für primitive Typen und Referenztypen Der Unterschied
Jeder Wissenspunkt kann für separate Spezialforschung herausgenommen werden.
1 Der Konstruktor verfügt über ein Prototypattribut, das auf das Prototypobjekt des Konstruktors verweist Die Instanz teilt sich das gleiche A-Prototypobjekt.
2. Wenn eine Instanz generiert wird, wird ein neuer Heap-Speicher im Speicher generiert, da diese andere Instanzen belegen im Heapspeicher und beeinflussen sich nicht gegenseitig ;
3 Jede Instanz hat einen impliziten Prototyp __proto__, der auf das Prototypobjekt des Konstruktors verweist Situationen umfassen Folgendes:
4.1 Wenn es als Objektmethode aufgerufen wird, zeigt es auf denjenigen, der es aufruft (diese Frage betrifft hauptsächlich diesen Artikel)
4.2 Wenn es als Funktion aufgerufen wird, zeigt es auf die globales Variablenfenster der obersten Ebene
4.3 Als Konstruktor Wenn eine Funktion aufgerufen wird, also wenn der neue Operator eine Instanz generiert, zeigt diese im Konstruktor auf die Instanz
4.4 Im Aufruf- und Anwendungsmethoden, die Bindung des angegebenen This wird als angegebener Kontext angezeigt
5. Literal Quantitative Methode (Es gibt auch Informationen, die Literal in direkte Quantität übersetzen. Ich persönlich denke, dass die letztere Übersetzung tatsächlich mehr ist (intuitiv und anschaulich). Beim Zuweisen von Objekten und Arrays (das Wesentliche von Arrays sind auch Objekte) werden alle Ressourcen im Heapspeicher generiert Adresse der Ressource.
6. Die Suchregeln der Prototypenkette folgen dem Prinzip des kürzesten Pfades, d Wenn die Instanz selbst und die gesuchte Eigenschaft nicht in der gesamten Prototypenkette vorhanden sind, wird undefiniert zurückgegeben.
Der detaillierte Unterschied zwischen Zuweisungsanweisungen für die Zuweisung von primitiven Werten und den Referenztyp Aufgabe.
Es gibt im Grunde nichts zu erklären.
Sie können die Antwort erhalten, indem Sie direkt den Wert nehmen1 [1,2,1] 5
;
Child
Der Konstruktor zeigte ursprünglich auf Child
. In der Frage zeigte das Prototypobjekt der Klasse
auf eine Instanz der Klasse Child
in der objektorientierten JavaScript-Programmierung 🎜>Eine der VererbungsmethodenParent
. Hierbei ist zu beachten, dass auf die Instanz von Child.prototype
verweist, nicht auf die Klasse Parent
parent
Parent
. Sie können die Antwort direkt auf der Konsole ausgeben, um 11 [1,2,1] 5
Was hier verwirrend ist, ist, warum die letzte Spalte des Arrays, auf das this.b zeigt,
statt ist >
1
11
sucht dann nach this.b, weil child1 kein b-Attribut hat, daher wird das b-Attribut des übergeordneten Elements entlang der Prototypenkette abgerufen. Die ersten beiden Elemente sind Konstanten, was nichts aussagt Das letzte Element des Arrays ist eine Referenz, und der Zeiger hier ist kein dynamischer Zeiger, da er während des neuen Parent()-Schritts einmal ausgeführt wurde und bestimmt ist, auf die Ressource zu zeigen, auf die er zeigt parent.a, die Ressource, auf die das Attribut a in child1.__proto__ zeigt, also der Wert 1.
Es ist zu beachten, dass:
Die Antwort ist, dass es keine Auswirkungen hat. Warum haben Attribute, die auf dieselbe Adresse zu verweisen scheinen, unterschiedliche Werte? Denn wenn die übergeordnete Instanz generiert wird, zeigt this.a auf einen primitiven Wert 2, sodass dem dritten Element in this.b tatsächlich ein primitiver Wert zugewiesen wird, sodass es auf den ersten Blick wie eine Referenztypzuweisung aussieht, dies aber nicht der Fall ist. . Durch die Zuweisung primitiver Werte wird neuer Speicherplatz geöffnet, sodass die Werte von this.a und this.b[2] gleich sind, aber auf unterschiedliche Adressen im Heap-Speicher verweisen. Ausführlichere Erklärungen finden Sie in den empfohlenen Blogbeiträgen in [Erweiterte Lektüre].
Ändern Sie es nach der Instanziierung
Eine andere Möglichkeit besteht darin, die Get/Set-Methode für das a-Attribut festzulegen. Ja, immer wenn sich der Wert des a-Attributs ändert, wird der Wert von b[2] synchron geändert . Der Code und die laufenden Ergebnisse lauten wie folgt:
3.child2. show( )
4.parent.show()
parent ist eine Instanz der Parent-Klasse und Child.prorotype zeigt auf eine andere Instanz der Parent-Klasse. Die beiden sind zwei Ressourcen im Heap-Speicher und wirken sich nicht gegenseitig aus, sodass die oben genannten Vorgänge keine Auswirkungen auf die übergeordnete Klasse haben Beispiel, und die
Welche Änderungen sind aufgetreten, nachdem child1 die Methode change() ausgeführt hat?
this.b. push(this.a)
Aufgrund der dynamischen Zeigeeigenschaften von this zeigt this.b auf das b-Array in Child.prototype und this.a zeigt auf das a-Attribut von child1, also Child.prototype. b wird zu [1,2,1,11];
this.a = this.b.length
Die Punkte von this.a und this.b in this Die Aussage ist dasselbe wie Der vorherige Satz ist konsistent, daher ist das Ergebnis, dass child1.a zu 4;
this.c.demo = this.a++Da die eigenen Attribute von child1 nicht c sind, verweist this.c hier auf Child.prototype.c. Der Wert von this.a ist
4, was ein primitiver Typ ist Die Zuweisungsoperation weist den Wert direkt Child.prototype.c zu. Das Ergebnis der Demo ist 4, und this.a erhöht sich dann auf 5(4 + 1 = 5).
Daher wirken sich alle Anweisungen in , die sich auf das Prototypobjekt auswirken, auf das endgültige Ausgabeergebnis von child2.change()
child1
this.b.push(this.a)Aufgrund der dynamischen Zeigeeigenschaften davon zeigt this.b auf Für das b-Array auf Child.prototype zeigt this.a auf das a-Attribut von child2, sodass Child.prototype.b zu
[1,2,1,11,12];this.a = this.b.length
Die Richtungen von this.a und this.b in dieser Anweisung stimmen mit dem vorherigen Satz überein, sodass das Ergebnis ist, dass child2.a 5 wird;
this.c.demo = this.a++
Da das eigene Attribut von child2 dies nicht tut Wenn Sie das C-Attribut haben, zeigt this.c hier auf Child.prototype.c, sodass das Ausführungsergebnis Child ist. Der Wert von .prototype.c.demo ändert sich in den Wert 5 von child2.a, und child2.a wird schließlich auf erhöht 6 (5 + 1 = 6). Als nächstes führen Sie den Ausgabebefehl aus und das Endergebnis wird ausgegeben:
child2.show():6 [1,2,1,11 ,12] 5
Erweitertes DenkenAls ich war Bei der Lösung des Problems habe ich einen Fehler in this.c.demo = this.a++ gemacht. Ich dachte, dass hier eine Referenz übergeben würde, aber tatsächlich wurde ein Wert übergeben. Nach der Analyse verstehen wir das, weil this.a darauf verweist Wenn Sie einen Originalwert angeben, entspricht dies der Zuweisung des Originalwerts zum Objektattribut, sodass der Wert von child.c.demo nach der Zuweisung nicht mehr von Änderungen in child.a beeinflusst wird. Wenn child.a ein Referenztyp ist, wie sieht das Ergebnis aus?
Nach der Ausführung werden wir feststellen, dass der Wert von Child.prototype.c folgt Der Wert von child1.a ändert sich mit Änderungen, da der Wert von child1.a zu diesem Zeitpunkt ein Referenztyp ist und der Zuweisungsprozess dazu führt, dass Child.prototype.c und child1.a auf die Speicherplatzadresse derselben Ressource verweisen . Eine ausführlichere Erläuterung der Originaltypen und Referenztypen finden Sie im Blog „Erweiterte Lektüre“ am Ende dieses Artikels.
Ernte und Reflexion
Das obige ist der detaillierte Inhalt vonAnalyse einer Interviewfrage zur Javascript-Prototypkette (Details). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!