function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
Es gibt immer das Objekt mit der Bewertung = 3 zurück.
Aber wenn ich folgendes mache:
newtoy.__proto__.__proto__.__proto__
Die Kette kehrt schließlich zurück null
.
Wie würde ich auch im Internet Explorer die Null überprüfen, wenn keine __proto__
Eigenschaft vorhanden ist?
javascript
inheritance
prototype-programming
xdevel2000
quelle
quelle
newtoy.prototype
nicht gleich istnewtoy.constructor.prototype
und dahernewtoy.constructor.prototype
nicht aufgerufen wirdrating
. Ebensonewtoy.constructor.prototype.constructor.property
wird auch keine Eigenschaft aufgerufenrating
.newtoy.constructor.prototype
Wird daher eine Eigenschaft namens Rating haben. In ähnlicher Weisenewtoy.constructor.prototype.constructor.property
wird auch eine Eigenschaft namens Rating haben.__proto__
Vs.prototype
in JavaScript und wie funktioniert JavaScript.prototype
?Antworten:
Ich habe kürzlich versucht, meinen Kopf darum zu wickeln, und schließlich diese "Karte" entwickelt, von der ich denke, dass sie das ganze Licht über die Sache wirft
http://i.stack.imgur.com/KFzI3.png
Ich weiß, dass ich nicht der erste bin, der das erfunden hat, aber es war interessanter herauszufinden, als es zu finden :-). Wie auch immer, danach habe ich zB dieses andere Diagramm gefunden, von dem ich denke, dass es im Grunde dasselbe sagt:
Javascript-Objektlayout
Die überraschendste Sache für mich war die Entdeckung , dass die
Object.__proto__
PunkteFunction.prototype
, stattObject.prototype
, aber ich bin sicher , es gibt einen guten Grund dafür :-)Ich füge den im Bild erwähnten Code auch hier ein, wenn jemand ihn testen möchte. Beachten Sie, dass den Objekten einige Eigenschaften hinzugefügt werden, damit Sie nach einigen Sprüngen leicht erkennen können, wo wir uns befinden:
quelle
Object.__proto__
hingewiesen wird,Function.prototype
ist, dass esObject()
sich um eine native Funktion handelt, die ein leeres Objekt instanziiert. DaherObject()
ist eine Funktion. Sie werden feststellen, dass alle__proto__
Eigenschaften der anderen wichtigen nativen Typen darauf verweisenFunction.prototype
.Object
,Function
,String
,Number
, UndArray
alle erben den Funktionsprototyp.Object
selbst ist eine Funktion; Das Ergebnis der Ausführung von callableObject
(dh der Rückgabewert von runningObject()
) ist keine Funktion.constructor
ist eine vordefinierte [[DontEnum]] - Eigenschaft des Objekts, auf die dieprototype
Eigenschaft eines Funktionsobjekts zeigt, und zeigt zunächst auf das Funktionsobjekt selbst.__proto__
entspricht der internen Eigenschaft eines Objekts, dh seines tatsächlichen Prototyps.Wenn Sie ein Objekt mit dem
new
Operator erstellen , wird seine interne Eigenschaft [[Prototype]] auf das Objekt festgelegt, auf das dieprototype
Eigenschaft der Konstruktorfunktion zeigt .Dies bedeutet, dass die zum Erstellen des Objekts verwendete Konstruktorfunktion
.constructor
ausgewertet wird.__proto__.constructor
, und wie wir erfahren haben, wurde dieprotoype
Eigenschaft dieser Funktion zum Festlegen des [[Prototyps]] des Objekts verwendet.Daraus folgt, dass dies
.constructor.prototype.constructor
identisch ist mit.constructor
(solange diese Eigenschaften nicht überschrieben wurden); siehe hier für eine ausführlichere Erklärung.Wenn
__proto__
verfügbar, können Sie die eigentliche Prototypkette des Objekts durchlaufen. In einfachem ECMAScript3 ist dies nicht möglich, da JavaScript nicht für Hierarchien mit tiefer Vererbung entwickelt wurde.quelle
.constructor.prototype
Verkettung. Ich war mir auch unklar, obwohl ich nicht gesehen habe, dass.constructor
das gleich ist.__proto__.constructor
. Was einfach bedeutet, zwischen der Konstruktorfunktion und ihrem Prototyp zu wechseln.Die prototypische Vererbung in JavaScript basiert auf einer
__proto__
Eigenschaft in dem Sinne, dass jedes Objekt den Inhalt des Objekts erbt, auf das seine__proto__
Eigenschaft verweist .Die
prototype
Eigenschaft ist nur fürFunction
Objekte und nur dannnew
spezifisch, wenn der Operator zum Aufrufen einesFunction
als Konstruktor verwendet wird. In diesem Fall werden die erstellten Objekte__proto__
auf Konstruktoren gesetztFunction.prototype
.Dies bedeutet, dass das Hinzufügen zu
Function.prototype
automatisch alle Objekte widerspiegelt, auf die__proto__
verwiesen wirdFunction.prototype
.Ersetzen Konstruktor
Function.prototype
mit einem anderen Objekt nicht aktualisieren__proto__
Eigenschaft für eine der bereits vorhandenen Objekte.Beachten Sie, dass auf die
__proto__
Eigenschaft nicht direkt zugegriffen werden sollte. Stattdessen sollte Object.getPrototypeOf (Objekt) verwendet werden.Um die erste Frage zu beantworten, habe ich ein maßgeschneidertes Diagramm
__proto__
undprototype
Referenzen erstellt. Leider erlaubt mir der Stackoverflow nicht, das Bild mit "weniger als 10 Reputation" hinzuzufügen. Vielleicht ein anderes Mal.[Bearbeiten] In der Abbildung wird
[[Prototype]]
anstelle von verwendet,__proto__
da sich die ECMAScript-Spezifikation auf interne Objekte bezieht. Ich hoffe du kannst alles herausfinden.Hier sind einige Hinweise, die Ihnen helfen, die Abbildung zu verstehen:
Beachten Sie, dass die
constructor
Eigenschaft in erstellten Objekten nicht vorhanden ist, sondern vom Prototyp geerbt wird.quelle
new MyFunction()
erstellt eine Objektinstanz , die sein__proto__
auf seinen Ctor Prototyp beziehen sollte , die istMyFunction.prototype.
also warum tutMyFunction.prototype.__proto__
referes zuObject.prototype
? es sollte sich (wie mein erstes Beispiel) auf den Prototyp seines Ctors beziehen, derMyFunction.prototype
(beachten Sie, dass diesMyFunction.prototype
ein Beispiel istMyfunction
)Object
ist Eva undFunction
ist Adam, Adam (Function
) benutzt seinen Knochen (Function.prototype
), um Eva (Object
) zu erschaffen . Wer hat dann Adam (Function
) erschaffen ? - Der Erfinder der JavaScript-Sprache :-).Nach der Antwort von utsaina möchte ich weitere nützliche Informationen hinzufügen.
Es sollte nicht sein.
Object.__proto__
sollte NICHT auf zeigenObject.prototype
. Stattdessen wird die InstanzObject
o
,o.__proto__
sollte darauf zuObject.prototype
.(Verzeihen Sie mir, dass ich die Begriffe
class
undinstance
JavaScript verwende, aber Sie wissen es :-)Ich denke, die Klasse
Object
selbst ist ein Beispiel dafürFunction
, deshalbObject.__proto__ === Function.prototype
. Deshalb:Object
ist Eva undFunction
ist Adam, Adam (Function
) benutzt seinen Knochen (Function.prototype
), um Eva (Object
) zu erschaffen .Darüber hinaus ist sogar die Klasse
Function
selbst eine Instanz von sichFunction
selbst, das istFunction.__proto__ === Function.prototype
auch der GrundFunction === Function.constructor
Darüber hinaus ist die reguläre Klasse
Cat
eine Instanz vonFunction
, das heißtCat.__proto__ === Function.prototype
.Der Grund dafür ist, dass wir beim Erstellen einer Klasse in JavaScript tatsächlich nur eine Funktion erstellen, für die eine Instanz sein sollte
Function
.Object
undFunction
sind nur etwas Besonderes, aber sie sind immer noch Klassen, währendCat
es sich um eine reguläre Klasse handelt.In der Google Chrome JavaScript-Engine werden die folgenden 4 Faktoren berücksichtigt:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Sie sind alle
===
(absolut gleich) zu den anderen 3 und ihr Wert istfunction Empty() {}
OK. Wer erstellt dann das Special
function Empty() {}
(Function.prototype
)? Denk darüber nach :-)quelle
function Empty() {}
, Function.prototype usw. zu entsprechen? Welchen Code haben Sie in der Chrome-Konsole verwendet?function Empty() {}
in Google Chrome. Ich habe auch die Konsolenausgabe hinzugefügt._ _proto_ _
) von Function.prototype. So einfach ist das :)Ich weiß wirklich nicht, warum die Leute dich nicht korrigiert haben, wo das eigentliche Problem in deinem Verständnis liegt.
Dies würde es Ihnen viel leichter machen, das Problem zu erkennen
Mal sehen, was los ist:
Großartig, jetzt schauen wir uns das an
__proto__
Bitte denken Sie vorher an zwei Dinge
__proto__
:Wenn Sie ein Objekt mit dem
new
Operator erstellen , wird dessen interne[[Prototype]]
/proto__
Eigenschaft auf dieprototype
Eigenschaft (1) seinesconstructor function
oder "Erstellers" gesetzt, wenn Sie möchten.In JS fest codiert -:
Object.prototype.__proto__
istnull
.Nennen wir diese beiden Punkte "
bill
"Besser?
quelle
Jede Funktion erstellt ihren Prototyp. Wenn wir mit diesem Funktionskonstruktor ein Objekt erstellen, zeigt die Eigenschaft __proto__ meines Objekts auf den Prototyp dieser Funktion.
quelle
__proto__
Eigentum sagen .Wenn all diese Zahlen überwältigend waren, schauen wir uns an, was die Eigenschaften bedeuten.
STH.prototype
Beim Erstellen einer neuen Funktion wird parallel ein leeres Objekt erstellt und mit der Funktion über die
[[Prototype]]
Kette verknüpft . Um auf dieses Objekt zuzugreifen, verwenden wir dieprototype
Eigenschaft der Funktion.Beachten Sie, dass die
prototype
Eigenschaft nur für Funktionen verfügbar ist.STH.constructor
Das oben erwähnte Prototypobjekt hat keine Eigenschaften außer einem -
constructor
. Diese Eigenschaft stellt eine Funktion dar, mit der das Prototypobjekt erstellt wurde.Beim Erstellen einer
Gadget
Funktion haben wir auch ein Objekt wie erstellt{constructor: Gadget}
- das ist nichts dergleichenGadget.prototype
. Wieconstructor
auf eine Funktion bezieht , die ein Objekt - Prototyp erstellt,toy.constructor
darstelltGadget
Funktion. Wir schreibentoy.constructor.prototype
und wir bekommen{constructor: Gadget}
wieder.Daher gibt es einen Teufelskreis: Sie können verwenden
toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
und es wird immer seinGadget.prototype
.STH .__ proto__
Während
prototype
es sich um eine funktionsspezifische Eigenschaft handelt,__proto__
ist sie für alle Objekte verfügbar, während sie sich einfügtObject.prototype
. Es bezieht sich auf den Prototyp einer Funktion, die ein Objekt erstellen kann.Hier
toy.__proto__
istGadget.prototype
. DaGadget.prototype
ein Objekt ({}
) und Objekte mitObject
Funktion erstellt werden (siehe obiges Beispiel), erhalten wirObject.prototype
. Dies ist das höhere Objekt in JavaScript und__proto__
kann nur anzeigennull
.quelle
Kurze Antwort:
__proto__
ist ein Verweis auf dieprototype
Eigenschaft des Konstruktors, der das Objekt erstellt hat.Objekte in JavaScript
Ein JavaScript-Objekt ist ein integrierter Typ für eine Sammlung von null oder mehr Eigenschaften. Eigenschaften sind Container, die andere Objekte, Grundwerte oder Funktionen enthalten.
Konstruktoren in JavaScript
Funktionen sind reguläre Objekte (die
[[Call]]
in ECMA-262-Begriffen implementiert sind) mit der zusätzlichen Fähigkeit, aufrufbar zu sein, spielen jedoch eine andere Rolle in JavaScript: Sie werden zu Konstruktoren ( Fabriken für Objekte), wenn sie über dennew
Operator aufgerufen werden . Konstruktoren sind daher ein grobes Analogon zu Klassen in anderen Sprachen.Jede JavaScript-Funktion ist tatsächlich eine Instanz des
Function
integrierten Funktionsobjekts mit einer speziellen Eigenschaft namens,prototype
die zum Implementieren der prototypbasierten Vererbung und der gemeinsamen Eigenschaften verwendet wird. Jedes von einer Konstruktorfunktion erstellte Objekt hat einen impliziten Verweis (als Prototyp oder bezeichnet__proto__
) auf den Wert seines Konstruktorsprototype
.Der Konstruktor
prototype
ist eine Art Blaupause zum Erstellen von Objekten, da jedes vom Konstruktor erstellte Objekt einen Verweis auf sein Objekt erbtprototype
.Die Prototypkette
Ein Objekt gibt seinen Prototyp über die interne Eigenschaft
[[Prototype]]
oder an__proto__
. Bei der Prototypbeziehung zwischen zwei Objekten geht es um Vererbung: Jedes Objekt kann ein anderes Objekt als Prototyp haben. Der Prototyp kann dernull
Wert sein.Die durch die
__proto__
Eigenschaft verbundene Objektkette wird als Prototypkette bezeichnet . Wenn auf eine Eigenschaft in einem Objekt verwiesen wird, bezieht sich diese Referenz auf die Eigenschaft, die im ersten Objekt in der Prototypenkette gefunden wurde, die eine Eigenschaft dieses Namens enthält. Die Prototypenkette verhält sich wie ein einzelnes Objekt.Siehe dieses Bild (aus diesem Blog extrahiert ):
Wenn Sie versuchen, auf eine Eigenschaft in einem Objekt zuzugreifen, startet JavaScript die Suche in diesem Objekt und setzt den Prototyp, den Prototyp des Prototyps usw. fort, bis die Eigenschaft gefunden wird oder wenn
__proto__
der Wert vorhanden istnull
.Fast alle Objekte sind Instanzen von
Object
, weilObject.prototype
es das letzte in ihrer Prototypenkette ist. IstObject.prototype
aber keine Instanz vonObject
weilObject.prototype.__proto__
hält den Wertnull
.Sie können auch ein Objekt mit einem erstellen
null
Prototyp wie dem folgenden :Ein solches Objekt ist eine bessere Karte (Wörterbuch) als ein wörtliches Objekt, weshalb dieses Muster manchmal als Diktat bezeichnet wird ( Diktat für Wörterbuch) bezeichnet wird.
Hinweis: wörtliche Objekte erstellt
{}
sind Instanzen ,Object
da({}).__proto__
ist ein Verweis aufObject.prototype
.quelle