Start · Sprachen · JavaScript · Referenz · Object.setPrototypeOf()

Object.setPrototypeOf()

Methode

Die statische Methode <code>Object.setPrototypeOf()</code> setzt den Prototype (interne <code>[[Prototype]]</code>-Eigenschaft) eines Objekts auf ein anderes Objekt oder <code>null</code>.

Kategorie: method-property

Signatur

Object.setPrototypeOf(obj, prototype)

Beschreibung

Die statische Methode Object.setPrototypeOf() setzt den Prototype (d. h. die interne [[Prototype]]-Eigenschaft) eines angegebenen Objekts auf ein anderes Objekt oder null.

Warnung: Das Ändern des [[Prototype]] eines Objekts ist aufgrund der Art und Weise, wie moderne JavaScript-Engines Property-Zugriffe optimieren, derzeit in jedem Browser und in jeder JavaScript-Engine eine sehr langsame Operation. Zusätzlich sind die Auswirkungen einer Änderung der Vererbung subtil und weitreichend und beschränken sich nicht auf die Zeit, die in der Object.setPrototypeOf(...)-Anweisung verbracht wird, sondern können sich auf jeden Code erstrecken, der Zugriff auf ein Objekt hat, dessen [[Prototype]] verändert wurde.

Da dieses Feature Teil der Sprache ist, liegt es weiterhin in der Verantwortung der Engine-Entwickler, dieses Feature (idealerweise) performant zu implementieren. Bis Engine-Entwickler dieses Problem beheben, sollten Sie, wenn Sie sich um die Performance sorgen, das Setzen des [[Prototype]] eines Objekts vermeiden. Erstellen Sie stattdessen ein neues Objekt mit dem gewünschten [[Prototype]] mithilfe von Object.create().

Beschreibung

Object.setPrototypeOf() gilt allgemein als der richtige Weg, den Prototype eines Objekts zu setzen. Sie sollten es stets gegenüber dem veralteten Object.prototype.__proto__-Accessor bevorzugen.

Wenn der Parameter obj kein Objekt ist (z. B. Zahl, String etc.), tut diese Methode nichts – ohne es in ein Objekt umzuwandeln oder zu versuchen, seinen Prototype zu setzen – und gibt obj direkt als primitiven Wert zurück. Wenn prototype denselben Wert wie der Prototype von obj hat, wird obj direkt zurückgegeben, ohne einen TypeError zu verursachen, selbst wenn obj einen unveränderlichen Prototype hat.

Aus Sicherheitsgründen gibt es bestimmte eingebaute Objekte, die einen unveränderlichen Prototype haben. Dies verhindert Prototype-Pollution-Angriffe, insbesondere Proxy-bezogene. Der Sprachkern spezifiziert nur Object.prototype als immutable prototype exotic object, dessen Prototype immer null ist. In Browsern sind window und location zwei weitere sehr häufige Beispiele.

Parameter

Name Typ Default Beschreibung
$obj Pflicht Object Das Objekt, dessen Prototype gesetzt werden soll.
$prototype Pflicht Object | null Der neue Prototype des Objekts (ein Objekt oder null).

Rückgabewert

Typ
Object
Beschreibung
Das angegebene Objekt.

Beispiele

Immutable Prototype

Object.isExtensible(Object.prototype); // true; you can add more properties
Object.setPrototypeOf(Object.prototype, {}); // TypeError: Immutable prototype object '#<Object>' cannot have their prototype set
Object.setPrototypeOf(Object.prototype, null); // No error; the prototype of `Object.prototype` is already `null`

Pseudoklassische Vererbung mit Klassen

class Human {}
class SuperHero extends Human {}

const superMan = new SuperHero();

Pseudoklassische Vererbung mit Object.setPrototypeOf()

function Human(name, level) {
  this.name = name;
  this.level = level;
}

function SuperHero(name, level) {
  Human.call(this, name, level);
}

Object.setPrototypeOf(SuperHero.prototype, Human.prototype);

// Set the `[[Prototype]]` of `SuperHero.prototype`
// to `Human.prototype`
// To set the prototypal inheritance chain

Human.prototype.speak = function () {
  return `${this.name} says hello.`;
};

SuperHero.prototype.fly = function () {
  return `${this.name} is flying.`;
};

const superMan = new SuperHero("Clark Kent", 1);

console.log(superMan.fly());
console.log(superMan.speak());

Subclassing ohne extends

class Human {}
class SuperHero {}

// Set the instance properties
Object.setPrototypeOf(SuperHero.prototype, Human.prototype);

// Hook up the static properties
Object.setPrototypeOf(SuperHero, Human);

const superMan = new SuperHero();

// Wichtig · Fallstricke

Wirft einen TypeError, wenn: der Parameter obj undefined oder null ist; obj nicht erweiterbar (non-extensible) ist oder ein immutable prototype exotic object wie Object.prototype oder window; der Parameter prototype kein Objekt und nicht null ist. Der Fehler wird jedoch nicht geworfen, wenn der neue Prototype denselben Wert wie der ursprüngliche Prototype von obj hat. Es ist nicht ratsam, setPrototypeOf() anstelle von extends zu verwenden – aus Performance- und Lesbarkeitsgründen.