Object.prototype.constructor
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Dieconstructor
Dateneigenschaft einerObject
-Instanz gibt eine Referenz auf die Konstruktorfunktion zurück, die das Instanzobjekt erstellt hat. Beachten Sie, dass der Wert dieser Eigenschaft eine Referenz aufdie Funktion selbst ist und nicht ein String, der den Namen der Funktion enthält.
Hinweis:Dies ist eine Eigenschaft von JavaScript-Objekten. Für dieconstructor
-Methode in Klassen, siehedie eigene Referenzseite.
Wert
Eine Referenz auf die Konstruktorfunktion, die das Instanzobjekt erstellt hat.
Eigenschaften vonObject.prototype.constructor | |
---|---|
Schreibbar | ja |
Aufzählbar | nein |
Konfigurierbar | ja |
Hinweis:Diese Eigenschaft wird standardmäßig auf derprototype
-Eigenschaft jeder Konstruktorfunktion erstellt und wird von allen Objekten geerbt, die mit diesem Konstruktor erzeugt werden.
Beschreibung
Jedes Objekt (mit Ausnahme dernull
Prototyp-Objekte) wird eineconstructor
-Eigenschaft auf seinem[[Prototype]]
haben. Objekte, die mit Literalen erstellt wurden, werden ebenfalls eineconstructor
-Eigenschaft haben, die auf den Konstruktortyp für dieses Objekt verweist — zum Beispiel erstellen Array-LiteraleArray
-Objekte, undObjektliterale erstellen einfache Objekte.
const o1 = {};o1.constructor === Object; // trueconst o2 = new Object();o2.constructor === Object; // trueconst a1 = [];a1.constructor === Array; // trueconst a2 = new Array();a2.constructor === Array; // trueconst n = 3;n.constructor === Number; // true
Beachten Sie, dassconstructor
normalerweise von derprototype
-Eigenschaft des Konstruktors stammt. Wenn Sie eine längere Prototypen-Kette haben, können Sie normalerweise erwarten, dass jedes Objekt in der Kette eineconstructor
-Eigenschaft hat.
const o = new TypeError(); // Inheritance: TypeError -> Error -> Objectconst proto = Object.getPrototypeOf;Object.hasOwn(o, "constructor"); // falseproto(o).constructor === TypeError; // trueproto(proto(o)).constructor === Error; // trueproto(proto(proto(o))).constructor === Object; // true
Beispiele
Den Konstruktor eines Objekts anzeigen
Das folgende Beispiel erstellt einen Konstruktor (Tree
) und ein Objekt dieses Typs (theTree
). Das Beispiel zeigt dann dieconstructor
-Eigenschaft für das ObjekttheTree
an.
function Tree(name) { this.name = name;}const theTree = new Tree("Redwood");console.log(`theTree.constructor is ${theTree.constructor}`);
Dieses Beispiel zeigt die folgende Ausgabe:
theTree.constructor is function Tree(name) { this.name = name;}
Die constructor-Eigenschaft einem Objekt zuweisen
Man kann dieconstructor
-Eigenschaft von Nicht-Primitiven zuweisen.
const arr = [];arr.constructor = String;arr.constructor === String; // truearr instanceof String; // falsearr instanceof Array; // trueconst foo = new Foo();foo.constructor = "bar";foo.constructor === "bar"; // true// etc.
Dies überschreibt nicht die alteconstructor
-Eigenschaft — sie war ursprünglich im[[Prototype]]
der Instanz vorhanden, nicht als eigene Eigenschaft.
const arr = [];Object.hasOwn(arr, "constructor"); // falseObject.hasOwn(Object.getPrototypeOf(arr), "constructor"); // truearr.constructor = String;Object.hasOwn(arr, "constructor"); // true — the instance property shadows the one on its prototype
Aber selbst wennObject.getPrototypeOf(a).constructor
neu zugewiesen wird, ändert das nicht andere Verhaltensweisen des Objekts. Zum Beispiel wird das Verhalten voninstanceof
durchSymbol.hasInstance
und nicht durchconstructor
gesteuert:
const arr = [];arr.constructor = String;arr instanceof String; // falsearr instanceof Array; // true
Es gibt nichts, was dieconstructor
-Eigenschaft davor schützt, neu zugewiesen oder überschattet zu werden, daher sollte sie vermieden werden, um den Typ einer Variablen zu erkennen. Weniger fehleranfällige Methoden wieinstanceof
undSymbol.toStringTag
für Objekte odertypeof
für Primitive sollten bevorzugt werden.
Den Konstruktor des Prototyps einer Konstruktorfunktion ändern
Jeder Konstruktor hat eineprototype
-Eigenschaft, die beim Aufruf über dennew
-Operator zum[[Prototype]]
der Instanz wird.ConstructorFunction.prototype.constructor
wird daher, wie zuvor demonstriert, eine Eigenschaft auf dem[[Prototype]]
der Instanz.
Wenn jedochConstructorFunction.prototype
neu zugewiesen wird, geht dieconstructor
-Eigenschaft verloren. Zum Beispiel ist dies eine übliche Methode, um ein Vererbungsmuster zu erstellen:
function Parent() { // …}Parent.prototype.parentMethod = function () {};function Child() { Parent.call(this); // Make sure everything is initialized properly}// Pointing the [[Prototype]] of Child.prototype to Parent.prototypeChild.prototype = Object.create(Parent.prototype);
Derconstructor
von Instanzen vonChild
wirdParent
sein, daChild.prototype
neu zugewiesen wurde.
Dies ist normalerweise kein großes Problem — die Sprache greift fast nie auf dieconstructor
-Eigenschaft eines Objekts zu. Die einzige Ausnahme ist die Verwendung von[Symbol.species]
, um neue Instanzen einer Klasse zu erstellen, aber solche Fälle sind selten und Sie sollten ohnehin dieextends
-Syntax verwenden, um eingebaute Klassen zu unterklassen.
Stellen Sie jedoch sicher, dassChild.prototype.constructor
immer aufChild
selbst verweist, wenn ein Aufruferconstructor
verwendet, um von einer Instanz auf die ursprüngliche Klasse zuzugreifen. Betrachten Sie den folgenden Fall: Das Objekt hat die Methodecreate()
, um sich selbst zu erstellen.
function Parent() { // …}function CreatedConstructor() { Parent.call(this);}CreatedConstructor.prototype = Object.create(Parent.prototype);CreatedConstructor.prototype.create = function () { return new this.constructor();};new CreatedConstructor().create().create(); // TypeError: new CreatedConstructor().create().create is undefined, since constructor === Parent
Im obigen Beispiel wird eine Ausnahme ausgelöst, da derconstructor
aufParent
verweist. Um dies zu vermeiden, weisen Sie einfach den notwendigen Konstruktor zu, den Sie verwenden möchten.
function Parent() { // …}function CreatedConstructor() { // …}CreatedConstructor.prototype = Object.create(Parent.prototype, { // Return original constructor to Child constructor: { value: CreatedConstructor, enumerable: false, // Make it non-enumerable, so it won't appear in `for...in` loop writable: true, configurable: true, },});CreatedConstructor.prototype.create = function () { return new this.constructor();};new CreatedConstructor().create().create(); // it's pretty fine
Beachten Sie, dass es entscheidend ist, beim manuellen Hinzufügen derconstructor
-Eigenschaft die Eigenschaftnicht aufzählbar zu machen, damitconstructor
nicht infor...in
-Schleifen besucht wird — wie es normalerweise der Fall ist.
Wenn der obige Code wie zu viel Boilerplate aussieht, können Sie auch in Betracht ziehen,Object.setPrototypeOf()
zu verwenden, um die Prototypenkette zu manipulieren.
function Parent() { // …}function CreatedConstructor() { // …}Object.setPrototypeOf(CreatedConstructor.prototype, Parent.prototype);CreatedConstructor.prototype.create = function () { return new this.constructor();};new CreatedConstructor().create().create(); // still works without re-creating constructor property
Object.setPrototypeOf()
hat potenzielle Leistungseinbußen, da alle zuvor erstellten Objekte, die in der Prototypenkette beteiligt sind, neu kompiliert werden müssen; aber wenn der obige Initialisierungscode vor der Erstellung vonParent
oderCreatedConstructor
erfolgt, sollte der Effekt minimal sein.
Betrachten wir noch einen komplexeren Fall.
function ParentWithStatic() {}ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member propertyParentWithStatic.getStartPosition = function () { return this.startPosition;};function Child(x, y) { this.position = { x, y };}Child.prototype = Object.create(ParentWithStatic.prototype, { // Return original constructor to Child constructor: { value: Child, enumerable: false, writable: true, configurable: true, },});Child.prototype.getOffsetByInitialPosition = function () { const position = this.position; // Using this.constructor, in hope that getStartPosition exists as a static method const startPosition = this.constructor.getStartPosition(); return { offsetX: startPosition.x - position.x, offsetY: startPosition.y - position.y, };};new Child(1, 1).getOffsetByInitialPosition();// Error: this.constructor.getStartPosition is undefined, since the// constructor is Child, which doesn't have the getStartPosition static method
Damit dieses Beispiel richtig funktioniert, können wir die statischen Eigenschaften vonParent
aufChild
neu zuweisen:
// …Object.assign(Child, ParentWithStatic); // Notice that we assign it before we create() a prototype belowChild.prototype = Object.create(ParentWithStatic.prototype, { // Return original constructor to Child constructor: { value: Child, enumerable: false, writable: true, configurable: true, },});// …
Aber noch besser, wir können die Konstruktorfunktionen selbst wie Klassen mitextends
voneinander erben lassen.
function ParentWithStatic() {}ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member propertyParentWithStatic.getStartPosition = function () { return this.startPosition;};function Child(x, y) { this.position = { x, y };}// Properly create inheritance!Object.setPrototypeOf(Child.prototype, ParentWithStatic.prototype);Object.setPrototypeOf(Child, ParentWithStatic);Child.prototype.getOffsetByInitialPosition = function () { const position = this.position; const startPosition = this.constructor.getStartPosition(); return { offsetX: startPosition.x - position.x, offsetY: startPosition.y - position.y, };};console.log(new Child(1, 1).getOffsetByInitialPosition()); // { offsetX: -1, offsetY: -1 }
Auch hier kann die Verwendung vonObject.setPrototypeOf()
negative Leistungseffekte haben, stellen Sie daher sicher, dass es direkt nach der Konstruktor-Deklaration und vor der Erstellung von Instanzen passiert — um zu vermeiden, dass Objekte "verunreinigt" werden.
Hinweis:Das manuelle Aktualisieren oder Setzen des Konstruktors kann zu unterschiedlichen und manchmal verwirrenden Konsequenzen führen. Um dies zu vermeiden, definieren Sie einfach die Rolle vonconstructor
in jedem spezifischen Fall. In den meisten Fällen wirdconstructor
nicht verwendet und eine Neuzuweisung ist nicht erforderlich.
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-object.prototype.constructor |
Browser-Kompatibilität
Siehe auch
MDN-Feedback-Box
Diese Seite wurde automatisch aus dem Englischen übersetzt.