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

Object.getPrototypeOf()

Methode

Gibt den Prototyp (den internen <code>[[Prototype]]</code>) des angegebenen Objekts zurück, oder <code>null</code>, wenn keine geerbten Eigenschaften existieren.

seit JavaScript ES5 (ES2015: primitive Argumente werden in Objekte Kategorie: method-property

Signatur

Object.getPrototypeOf(obj)

Beschreibung

Object.getPrototypeOf() liest die interne Eigenschaft [[Prototype]] eines Objekts aus, also das Objekt, von dem es Eigenschaften und Methoden erbt. Die Methode ist der standardisierte, empfohlene Weg, um an den Prototyp zu kommen. Den veralteten Accessor obj.__proto__ sollte man dafür nicht mehr verwenden.

Typische Einsatzfälle sind das Untersuchen von Vererbungsketten (etwa beim Debugging oder in Bibliotheken), die Prüfung, ob ein Objekt ein „einfaches“ Objekt ist (Prototyp gleich Object.prototype oder null), sowie das Durchlaufen der gesamten Prototypkette bis zu null.

Seit ES2015 werden primitive Werte wie Zahlen oder Zeichenketten automatisch in ihr Wrapper-Objekt umgewandelt. Object.getPrototypeOf("abc") liefert deshalb String.prototype. Bei null und undefined wird dagegen ein TypeError geworfen.

Bei Proxy-Objekten kann die Falle getPrototypeOf das Ergebnis abfangen und verändern.

Parameter

Name Typ Default Beschreibung
$obj Pflicht any (außer null/undefined) Das Objekt, dessen Prototyp zurückgegeben werden soll. Primitive Werte werden in ihr Wrapper-Objekt umgewandelt.

Rückgabewert

Typ
object | null
Beschreibung
Den Prototyp von obj, oder null, wenn das Objekt keinen Prototyp hat (z. B. bei Object.create(null) oder bei Object.prototype selbst).

Beispiele

Prototyp von Klasseninstanzen prüfen

class Tier {}
class Hund extends Tier {}

const bello = new Hund();

console.log(Object.getPrototypeOf(bello) === Hund.prototype);
console.log(Object.getPrototypeOf(Hund.prototype) === Tier.prototype);
console.log(Object.getPrototypeOf(Hund) === Tier); // Auch Konstruktoren erben voneinander
true true true

Gesamte Prototypkette ausgeben

const prototypKette = (obj) => {
  const kette = [];
  let aktuell = Object.getPrototypeOf(obj);
  while (aktuell !== null) {
    kette.push(aktuell.constructor?.name ?? '(ohne Konstruktor)');
    aktuell = Object.getPrototypeOf(aktuell);
  }
  return kette;
};

console.log(prototypKette([1, 2, 3]));
console.log(prototypKette(new Map()));
[ 'Array', 'Object' ] [ 'Map', 'Object' ]

Einfaches Objekt (Plain Object) erkennen

const istPlainObject = (wert) => {
  if (typeof wert !== 'object' || wert === null) return false;
  const proto = Object.getPrototypeOf(wert);
  return proto === Object.prototype || proto === null;
};

console.log(istPlainObject({ a: 1 }));
console.log(istPlainObject(Object.create(null)));
console.log(istPlainObject(new Date()));
console.log(istPlainObject([]));
true true false false

Primitive Werte und Fehlerfall

console.log(Object.getPrototypeOf('Hallo') === String.prototype);
console.log(Object.getPrototypeOf(42) === Number.prototype);

try {
  Object.getPrototypeOf(null);
} catch (err) {
  console.log(err.constructor.name);
}
true true TypeError

// Wichtig · Fallstricke

  • TypeError bei null/undefined: Wer unbekannte Werte übergibt, sollte sie vorher prüfen.
  • Unterschied zu ES5: In ES5 warf die Methode bei primitiven Werten einen TypeError. Seit ES2015 werden sie in Objekte umgewandelt. Für sehr alte Umgebungen ist das relevant.
  • Nicht mit Function.prototype.prototype verwechseln: Object.getPrototypeOf(Foo) liefert den Prototyp der Funktion selbst (meist Function.prototype), nicht Foo.prototype.
  • Realm-übergreifend: Objekte aus anderen iframes oder vm-Kontexten haben ein eigenes Object.prototype. Vergleiche mit === schlagen dann fehl.
  • __proto__ meiden: Der Accessor ist nur aus Kompatibilitätsgründen spezifiziert (Annex B) und fehlt bei Objekten ohne Prototyp. Object.getPrototypeOf() funktioniert dagegen immer.
  • Das Gegenstück Object.setPrototypeOf() ist sehr langsam, weil Engines ihre Optimierungen verwerfen müssen. Das Lesen mit getPrototypeOf ist dagegen unkritisch.
  • Kompatibilität: In allen modernen Browsern und in Node.js verfügbar (Baseline).