[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor [Back]  [Original]

Object.prototype.constructor - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

Object.prototype.constructor

Baseline Weitgehend verfgbar

Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Juli 2015 browserbergreifend verfgbar.

Die constructor Dateneigenschaft einer Object-Instanz gibt eine Referenz auf die Konstruktorfunktion zurck, die das Instanzobjekt erstellt hat. Beachten Sie, dass der Wert dieser Eigenschaft eine Referenz auf die Funktion selbst ist und nicht ein String, der den Namen der Funktion enthlt.

Hinweis: Dies ist eine Eigenschaft von JavaScript-Objekten. Fr die constructor-Methode in Klassen, siehe die eigene Referenzseite.

In diesem Artikel

Wert

Eine Referenz auf die Konstruktorfunktion, die das Instanzobjekt erstellt hat.

Eigenschaften von Object.prototype.constructor
Schreibbarja
Aufzhlbarnein
Konfigurierbarja

Hinweis: Diese Eigenschaft wird standardmig auf der prototype-Eigenschaft jeder Konstruktorfunktion erstellt und wird von allen Objekten geerbt, die mit diesem Konstruktor erzeugt werden.

Beschreibung

Jedes Objekt (mit Ausnahme der null Prototyp-Objekte) wird eine constructor-Eigenschaft auf seinem [[Prototype]] haben. Objekte, die mit Literalen erstellt wurden, werden ebenfalls eine constructor-Eigenschaft haben, die auf den Konstruktortyp fr dieses Objekt verweist zum Beispiel erstellen Array-Literale Array-Objekte, und Objektliterale erstellen einfache Objekte.

js
const o1 = {};
o1.constructor === Object; // true

const o2 = new Object();
o2.constructor === Object; // true

const a1 = [];
a1.constructor === Array; // true

const a2 = new Array();
a2.constructor === Array; // true

const n = 3;
n.constructor === Number; // true

Beachten Sie, dass constructor normalerweise von der prototype-Eigenschaft des Konstruktors stammt. Wenn Sie eine lngere Prototypen-Kette haben, knnen Sie normalerweise erwarten, dass jedes Objekt in der Kette eine constructor-Eigenschaft hat.

js
const o = new TypeError(); // Inheritance: TypeError -> Error -> Object
const proto = Object.getPrototypeOf;

Object.hasOwn(o, "constructor"); // false
proto(o).constructor === TypeError; // true
proto(proto(o)).constructor === Error; // true
proto(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 die constructor-Eigenschaft fr das Objekt theTree an.

js
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 die constructor-Eigenschaft von Nicht-Primitiven zuweisen.

js
const arr = [];
arr.constructor = String;
arr.constructor === String; // true
arr instanceof String; // false
arr instanceof Array; // true

const foo = new Foo();
foo.constructor = "bar";
foo.constructor === "bar"; // true

// etc.

Dies berschreibt nicht die alte constructor-Eigenschaft sie war ursprnglich im [[Prototype]] der Instanz vorhanden, nicht als eigene Eigenschaft.

js
const arr = [];
Object.hasOwn(arr, "constructor"); // false
Object.hasOwn(Object.getPrototypeOf(arr), "constructor"); // true

arr.constructor = String;
Object.hasOwn(arr, "constructor"); // true  the instance property shadows the one on its prototype

Aber selbst wenn Object.getPrototypeOf(a).constructor neu zugewiesen wird, ndert das nicht andere Verhaltensweisen des Objekts. Zum Beispiel wird das Verhalten von instanceof durch Symbol.hasInstance und nicht durch constructor gesteuert:

js
const arr = [];
arr.constructor = String;
arr instanceof String; // false
arr instanceof Array; // true

Es gibt nichts, was die constructor-Eigenschaft davor schtzt, neu zugewiesen oder berschattet zu werden, daher sollte sie vermieden werden, um den Typ einer Variablen zu erkennen. Weniger fehleranfllige Methoden wie instanceof und Symbol.toStringTag fr Objekte oder typeof fr Primitive sollten bevorzugt werden.

Den Konstruktor des Prototyps einer Konstruktorfunktion ndern

Jeder Konstruktor hat eine prototype-Eigenschaft, die beim Aufruf ber den new-Operator zum [[Prototype]] der Instanz wird. ConstructorFunction.prototype.constructor wird daher, wie zuvor demonstriert, eine Eigenschaft auf dem [[Prototype]] der Instanz.

Wenn jedoch ConstructorFunction.prototype neu zugewiesen wird, geht die constructor-Eigenschaft verloren. Zum Beispiel ist dies eine bliche Methode, um ein Vererbungsmuster zu erstellen:

js
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.prototype
Child.prototype = Object.create(Parent.prototype);

Der constructor von Instanzen von Child wird Parent sein, da Child.prototype neu zugewiesen wurde.

Dies ist normalerweise kein groes Problem die Sprache greift fast nie auf die constructor-Eigenschaft eines Objekts zu. Die einzige Ausnahme ist die Verwendung von [Symbol.species], um neue Instanzen einer Klasse zu erstellen, aber solche Flle sind selten und Sie sollten ohnehin die extends-Syntax verwenden, um eingebaute Klassen zu unterklassen.

Stellen Sie jedoch sicher, dass Child.prototype.constructor immer auf Child selbst verweist, wenn ein Aufrufer constructor verwendet, um von einer Instanz auf die ursprngliche Klasse zuzugreifen. Betrachten Sie den folgenden Fall: Das Objekt hat die Methode create(), um sich selbst zu erstellen.

js
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 ausgelst, da der constructor auf Parent verweist. Um dies zu vermeiden, weisen Sie einfach den notwendigen Konstruktor zu, den Sie verwenden mchten.

js
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 Hinzufgen der constructor-Eigenschaft die Eigenschaft nicht aufzhlbar zu machen, damit constructor nicht in for...in-Schleifen besucht wird wie es normalerweise der Fall ist.

Wenn der obige Code wie zu viel Boilerplate aussieht, knnen Sie auch in Betracht ziehen, Object.setPrototypeOf() zu verwenden, um die Prototypenkette zu manipulieren.

js
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 Leistungseinbuen, da alle zuvor erstellten Objekte, die in der Prototypenkette beteiligt sind, neu kompiliert werden mssen; aber wenn der obige Initialisierungscode vor der Erstellung von Parent oder CreatedConstructor erfolgt, sollte der Effekt minimal sein.

Betrachten wir noch einen komplexeren Fall.

js
function ParentWithStatic() {}

ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member property
ParentWithStatic.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, knnen wir die statischen Eigenschaften von Parent auf Child neu zuweisen:

js
// 
Object.assign(Child, ParentWithStatic); // Notice that we assign it before we create() a prototype below
Child.prototype = Object.create(ParentWithStatic.prototype, {
  // Return original constructor to Child
  constructor: {
    value: Child,
    enumerable: false,
    writable: true,
    configurable: true,
  },
});
// 

Aber noch besser, wir knnen die Konstruktorfunktionen selbst wie Klassen mit extends voneinander erben lassen.

js
function ParentWithStatic() {}

ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member property
ParentWithStatic.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 von Object.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 fhren. Um dies zu vermeiden, definieren Sie einfach die Rolle von constructor in jedem spezifischen Fall. In den meisten Fllen wird constructor nicht verwendet und eine Neuzuweisung ist nicht erforderlich.

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# sec-object.prototype.constructor

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page