2016-04-10 15 views
2

Ich habe Frage, vielleicht ein bisschen ungewöhnlich, über den Prototyp einer Funktion, diesen Code sehen und die Kommentare beachten, die die Ausgabe der Konsole:Verständnis Funktionsprototyp und __proto__

function Foo() { 
 
}; 
 

 
var o = Foo.prototype; 
 

 
console.log(o.__proto__); // Object {} 
 
console.log(o.constructor); // function Foo() {} 
 
console.log(o.__proto__.constructor); // function Object() { [native code] } 
 

 
console.log(o.__proto__.constructor === o.constructor); // false

Bitte ignoriere, dass ich __proto__ anstelle des Standards getPrototypeOf() verwende.

Ich versuche herauszufinden, warum die letzte Zeile false ausdruckt. Wir wissen in der Regel, dass für jedes Objekt die folgenden Punkte zutrifft:

obj.__proto__.constructor === obj.constructor

Wir freuen uns, zu verstehen, warum dies nicht im Falle von o oben ist als o ist ein zu Objekt.

Ich frage mich, wenn es falsch ist, weil o eigentlich ein Prototyp Instanz Funktion ist (Foo.prototype), und daher wird es o.constructor Set Foo während Foo Setup.

Ich weiß, dass dies nicht viel praktischen Nutzen haben kann, aber es ist nützlich, einige Dinge zu verstehen.

+0

"* Wir wissen normalerweise, dass für jedes Objekt das Folgende zutrifft:' obj .__ proto __. Constructor === obj.constructor' * "- jedes Objekt ohne eigene' .constructor'-Eigenschaft, das heißt. Und 'Foo.prototype' * hat * eine eigene 'Konstruktor'-Eigenschaft, die auf' Foo' zeigt. – Bergi

+0

@Bergi jedes Objekt hat eine "Konstruktor" -Eigenschaft, denke ich. Es ist von "Object.prototype" geerbt, das die "constructor" -Eigenschaft hat. Nicht sicher, was du meintest, wenn du bitte ein bisschen ins Detail gehst, wäre das nützlich, danke. –

+0

Ich meinte eigene Eigenschaften, keine geerbten. Und Sie können sogar Objekte erzeugen, die nicht von "Object.prototype" abstammen, so dass sie überhaupt keine ".constructor" -Eigenschaft hätten (zB "" constructor "in Object.create (null)' ist false) – Bergi

Antwort

3

Dies ist keine unveränderliche:

Object.getPrototypeOf(obj).constructor === obj.constructor 

Stattdessen ist es nur, dass Menschen in der Regel nicht hinzufügen benutzerdefinierte constructor Eigenschaften, um ihre Objekte und die meisten Objekte sind nicht prototype Objekte eines Konstruktor. Wenn Sie auf constructor Eigenschaft zugreifen, erhalten Sie daher den Wert, der von dem Prototyp [Prototyp] geerbt wird (falls vorhanden).

function Foo(){} 
Foo.prototype.constructor; // Foo (own property) 
new Foo().constructor; // Foo (inherited from Foo.prototype) 

jedoch prototype Objekte eines Konstruktor haben eine eigene constructor Eigenschaft haben standardmäßig, die als die constructor ihrer in der Regel verschieden ist [[Prototyp]] (falls vorhanden).

function Foo(){} 
Foo.prototype.constructor; // Foo (own property) 
var proto = Object.getPrototypeOf(Foo.prototype); // Object.prototype 
proto.constructor; // Object (own property of proto/Object.prototype) 

Denken Sie daran, es ist nichts Besonderes constructor, es ist nur eine normale Eigenschaft, die in prototype Objekte eines Konstruktor automatisch erstellt wird Sie den Konstruktor von einer Instanz zu helfen. Sie können sie jedoch ändern, löschen oder schattieren.

+0

's/Allerdings, Konstrukteure/Allerdings, Prototypen /' iiuc – Siguza

+0

@Oriol: Danke. Wäre es richtig zu sagen, dass "Foo.prototype.constructor" sich von "Object.getPrototypeOf (Foo.prototype) .constructor" unterscheidet, denn wenn 'Foo.prototype' erstellt wurde, hat die JS-Engine so etwas wie' Foo.prototype 'gemacht. Konstruktor = Foo', und auf diese Weise hat es den geerbten 'Konstruktor'-Eigenschaftswert von 'Object.prototype.constructor' verändert? –

+0

Ich wünschte nur, jemand könnte bloggen oder schreiben irgendwo Pseudocode basierend auf dem tatsächlichen C++ - Code aus einer JS-Engine, um zu zeigen, wie 'Prototyp' und' Konstruktor' für 'Function' und' Object' gesetzt sind. Es würde etwas Licht auf die Verwirrung darüber werfen, wie diese Dinge in JS funktionieren. –

Verwandte Themen