Es gibt viele und chaotische Beziehungen in JavaScript. Die Bereichskette ist eine Einwegkettenbeziehung, die recht einfach und klar ist. Die aufrufende Beziehung dieses Mechanismus ist etwas kompliziert. Und was den Prototyp betrifft, ist es eine dreieckige Beziehung zwischen Prototyp, Proto und Konstruktor. Dieser Artikel verwendet zuerst ein Bild, um die Bedeutung zu klären, und erklärt dann die Dreieck -Beziehung des Prototyps im Detail.
Illustration
Konzept
Die komplexe Beziehung im obigen Bild stammt tatsächlich aus zwei Codezeilen
Funktion foo () {}; var f1 = new foo;【Konstruktor】
Die Funktion, mit der das neu erstellte Objekt initialisiert wird, ist der Konstruktor. Im Beispiel ist die FOO () -Funktion ein Konstruktor
【Instanzobjekt】
Das vom neue Betrieb des Konstruktors erstellte Objekt ist ein Instanzobjekt. Sie können einen Konstruktor verwenden, um mehrere Instanzobjekte zu konstruieren
Funktion foo () {}; var f1 = new foo; var f2 = new foo; console.log (f1 === F2); // false【Prototypobjekte und Prototyp】
Der Konstruktor verfügt über eine Prototyp -Eigenschaft, die auf das Prototypobjekt des Instanzobjekts hinweist. Mehrere Objekte, die durch denselben Konstruktor instanziiert sind, haben das gleiche Prototypobjekt. Verwenden Sie regelmäßig Prototypobjekte, um die Vererbung zu erreichen
Funktion foo () {}; foo.prototype.a = 1; var f1 = new foo; var f2 = new foo; console.log (foo.prototype.a); // 1console.log (f1.a); // 1console.log (f2.a);【Konstruktor】
Das Prototyp -Objekt hat ein Konstruktorattribut, das auf die Konstruktorfunktion hinweist, die dem Prototyp -Objekt entspricht.
Funktion foo () {}; console.log (foo.prototype.constructor === foo); // trueDa das Instanzobjekt die Eigenschaften des Prototyp -Objekts erben kann, hat das Instanzobjekt auch das Konstruktorattribut, das auch auf die Konstruktorfunktion zeigt, die dem Prototyp -Objekt entspricht.
Funktion foo () {}; var f1 = new foo; console.log (f1.constructor === foo); // true【Proto】
Das Instanzobjekt hat ein Protoattribut, das auf das Prototypobjekt zeigt, das dem Instanzobjekt entspricht
Funktion foo () {}; var f1 = new foo; console.log (f1 .__ proto__ === foo.prototype); // trueveranschaulichen
Das Konzept wurde eingeführt, und jetzt werden wir die Beziehung im Detail erklären.
Funktion foo () {}; var f1 = new foo;【Teil 1: Foo】】】
Das Instanzobjekt F1 wird durch den neuen Betrieb des Konstruktors foo () erstellt. Das Prototypobjekt des Konstruktors foo () ist foo.prototyp; Das Instanzobjekt F1 verweist auch auf das Prototyp -Objekt foo.prototype über das __Proto__ -Attribut.
Funktion foo () {}; var f1 = new foo; console.log (f1 .__ proto === foo.prototype); // trueDas Instanzobjekt F1 selbst hat kein Konstruktorattribut, kann das Konstruktorattribut des Prototyp -Objekts foo.prototype erben.
Funktion foo () {}; var f1 = new foo; console.log (foo.prototype.constructor === Foo); // Trueconsole.log (f1.constructor === Foo); // trueconsole.log (f1.hasownProperty ('Constructor); // // falsey.Die folgende Abbildung zeigt den Konsoleneffekt des Instanzobjekts F1
【Teil 2: Objekt】
Foo.Prototyp ist das Prototypobjekt von F1 und auch ein Instanzobjekt. Tatsächlich kann jedes Objekt als Objekt angesehen werden, das durch den neuen Betrieb des Object () -Konstruktors instanziiert wird. Foo.Prototype ist also ein Instanzobjekt, sein Konstruktor ist Object () und das Prototyp -Objekt ist Object.Prototyp. Dementsprechend verweist die Prototyp -Eigenschaft des Konstruktorobjekts () auf das Prototyp -Objekt. Die Protoeigenschaft des Instanzobjekts foo.Prototype zeigt auch auf das Prototyp -Objektobjekt
Funktion foo () {}; var f1 = new foo; console.log (foo.prototype .__ proto__ === Objekt.Prototyp); // trueDas Instanzobjekt foo.prototypen selbst hat das Konstruktorattribut, so dass das Konstruktorattribut vom Prototype -Objekt Objekt.Prototype geerbt wurde.
Funktion foo () {}; var f1 = new foo; console.log (foo.prototype.constructor === FOO); // Trueconsole.log (Object.Prototype.Constructor === " Objekt); // trueconsole.log (foo.prototype.hasownProperty ('Konstruktor'); // Trueconsole.log (foo.prototype.hasownProperty ('Constructor'); // trueDie folgende Abbildung zeigt den Konsoleneffekt des Instanzobjekts foo.prototype
Wenn Object.Prototype ein Instanzobjekt ist, wie lautet das Prototyp -Objekt? Das Ergebnis ist null. Ich denke, dies kann auch das Ergebnis von Typeof Null sein, was einer der Gründe ist, warum "Objekt"
console.log (Object.Prototype .__ proto__ === null); // true
【Teil 3: Funktion】
Wie bereits erwähnt, sind Funktionen Objekte, aber Objekte mit besonderen Funktionen. Jede Funktion kann als Ergebnis der Instanziierung durch den neuen Betrieb des Funktionskonstruktors () angesehen werden.
Wenn die Funktion foo als Instanzobjekt angesehen wird, ist sein Konstruktor Funktion () und ihr Prototyp -Objekt ist Funktion.Prototyp; In ähnlicher Weise ist der Konstruktor des Funktionsobjekts auch Funktion () und sein Prototyp -Objekt ist Funktion.Prototyp.
Funktion foo () {}; var f1 = new foo; console.log (foo .__ proto__ === functionDas Konstruktorattribut der Prototyp -Objektfunktion. Prototyp zeigt auf die Konstruktorfunktion (); Das Instanzobjektobjekt und FOO haben nicht das Konstruktorattribut, und es ist erforderlich, das Konstruktorattribut der Prototyp -Objektfunktion zu erben.
Funktion foo () {}; var f1 = new foo; console.log (function.prototype.constructor === Funktion); // Trueconsole.Log (foo.constructor ============== // trueconsole.log (foo.hasownProperty ('constructor'); Funktion); // trueconsole.log (Object.hasownProperty ('Konstruktor')); // falseAlle Funktionen können als instanziierte Objekte des neuen Betriebs der Konstruktorfunktion () angesehen werden. Anschließend kann die Funktion als Ergebnis des Aufrufens einer eigenen neuen Operation -Instanziierung angesehen werden.
Wenn also Funktion ein Instanzobjekt ist, ist sein Konstruktor die Funktion und ihr Prototypobjekt ist Funktion.Prototype
console.log (Funktion .__ proto__ === function.prototype); // trueconsole.log (function.prototype.constructor === Funktion); // trueconsole.log (function.Prototype === Funktion); // trueconsole.log (function.Prototype == Function); // True true.
Wenn function.Prototype ein Instanzobjekt ist, wie lautet das Prototyp -Objekt? Nach wie vor können alle Objekte als Instanziierungsergebnis des neuen Betriebs des Object () -Konstruktors angesehen werden. Daher ist das Prototyp -Objekt der Funktion.
console.log (function.prototype .__ proto__ === Object.Prototype); // true
Der zweite Teil führt vor, dass das Prototypobjekt von Object.Prototype null ist
console.log (Object.Prototype .__ proto__ === null); // true
Zusammenfassen
【1】 Die Funktion (Funktion ist auch eine Funktion) ist das Ergebnis einer neuen Funktion, sodass die Funktion als Instanzobjekt verwendet werden kann, sein Konstruktor ist Funktion () und das Prototyp -Objekt ist Funktion.Prototype
【2】 Objekte (Funktionen sind auch Objekte) sind das Ergebnis eines neuen Objekts, sodass das Objekt als Instanzobjekt verwendet werden kann, sein Konstruktor ist objekt () und das Prototyp -Objekt ist Object.Prototype
【3】 Object.Prototype Prototyp -Objekt ist null