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

Object.getOwnPropertyDescriptor()

Methode

Gibt den Eigenschafts-Deskriptor einer <strong>eigenen</strong> Eigenschaft eines Objekts zurück oder <code>undefined</code>, wenn es sie nicht gibt.

seit JavaScript ES5 (ES2015: Primitive als Argument erlaubt) Kategorie: method-property

Signatur

Object.getOwnPropertyDescriptor(obj, prop)

Beschreibung

Object.getOwnPropertyDescriptor() liefert ein einfaches Objekt, das die Konfiguration einer Eigenschaft beschreibt. Berücksichtigt werden nur Eigenschaften, die direkt auf dem Objekt definiert sind. Eigenschaften aus der Prototypenkette werden nicht gefunden. Gibt es die Eigenschaft nicht, ist der Rückgabewert undefined.

Es gibt zwei Arten von Deskriptoren:

  • Daten-Deskriptor: value, writable, enumerable, configurable
  • Accessor-Deskriptor: get, set, enumerable, configurable

Praktisch ist die Methode vor allem, um Getter und Setter herauszulesen (etwa um sie zu kopieren oder zu umhüllen), um zu prüfen, ob eine Eigenschaft schreibgeschützt oder eingefroren ist, und bei Metaprogrammierung zusammen mit Object.defineProperty() oder in Proxy-Traps.

Das zurückgegebene Objekt ist eine Kopie. Wenn du es änderst, ändert sich die ursprüngliche Eigenschaft nicht. Dafür musst du den geänderten Deskriptor wieder an Object.defineProperty() übergeben.

Parameter

Name Typ Default Beschreibung
$obj Pflicht Object Das Objekt, auf dem nach der Eigenschaft gesucht wird. Primitive Werte werden seit ES2015 in ein Objekt umgewandelt. null und undefined lösen einen TypeError aus.
$prop Pflicht string|symbol Name oder Symbol der Eigenschaft. Andere Werte werden in einen String umgewandelt.

Rückgabewert

Typ
PropertyDescriptor | undefined
Beschreibung
Ein neues Objekt mit den Feldern value/writable bzw. get/set sowie enumerable und configurable. Ist die Eigenschaft nicht direkt auf dem Objekt vorhanden, wird undefined zurückgegeben.

Beispiele

Daten-Deskriptor einer normalen Eigenschaft

const user = { name: 'Anna' };
console.log(Object.getOwnPropertyDescriptor(user, 'name'));
{ value: 'Anna', writable: true, enumerable: true, configurable: true }

Getter aus einer Klasse auslesen

class Temperatur {
  #celsius = 20;
  get fahrenheit() { return this.#celsius * 9 / 5 + 32; }
}

// Getter liegen auf dem Prototyp, nicht auf der Instanz
const t = new Temperatur();
console.log(Object.getOwnPropertyDescriptor(t, 'fahrenheit'));

const desc = Object.getOwnPropertyDescriptor(Temperatur.prototype, 'fahrenheit');
console.log(typeof desc.get, desc.set, desc.enumerable);
console.log(desc.get.call(t));
undefined function undefined false 68

Prüfen, ob eine Eigenschaft schreibbar ist

const config = Object.freeze({ apiUrl: 'https://api.example.com' });

const istSchreibbar = (obj, key) => {
  const d = Object.getOwnPropertyDescriptor(obj, key);
  if (!d) return false;
  return 'value' in d ? d.writable : typeof d.set === 'function';
};

console.log(istSchreibbar(config, 'apiUrl'));
console.log(Object.getOwnPropertyDescriptor(config, 'apiUrl'));
false { value: 'https://api.example.com', writable: false, enumerable: false, configurable: false }

Setter umhüllen (Logging)

const konto = {
  _saldo: 0,
  get saldo() { return this._saldo; },
  set saldo(v) { this._saldo = v; }
};

const orig = Object.getOwnPropertyDescriptor(konto, 'saldo');
Object.defineProperty(konto, 'saldo', {
  ...orig,
  set(v) {
    console.log(`saldo: ${this._saldo} -> ${v}`);
    orig.set.call(this, v);
  }
});

konto.saldo = 100;
console.log(konto.saldo);
saldo: 0 -> 100 100

// Wichtig · Fallstricke

  • Nur eigene Eigenschaften: Geerbte Eigenschaften wie Klassen-Getter oder toString ergeben undefined. Wenn du sie brauchst, musst du selbst mit Object.getPrototypeOf() die Prototypenkette durchlaufen.
  • Standardwerte: Eigenschaften, die per Object.defineProperty() angelegt werden, sind ohne ausdrückliche Angabe writable: false, enumerable: false und configurable: false. Bei Eigenschaften, die per Zuweisung entstehen, sind alle drei true.
  • Primitive: In ES5 löste Object.getOwnPropertyDescriptor('abc', 'length') einen TypeError aus. Seit ES2015 wird der Wert in ein Objekt umgewandelt, das Ergebnis ist dann { value: 3, writable: false, enumerable: false, configurable: false }.
  • Kopie: Wenn du den zurückgegebenen Deskriptor änderst, wirkt sich das nicht auf die Eigenschaft aus.
  • Proxy: Bei Proxys wird die Trap getOwnPropertyDescriptor ausgelöst. Sie muss Invarianten einhalten, sonst gibt es einen TypeError.
  • Mehrere Eigenschaften: Für alle Deskriptoren auf einmal gibt es Object.getOwnPropertyDescriptors() (ES2017). Damit lassen sich Objekte samt Gettern und Settern kopieren, was Object.assign() und der Spread-Operator nicht können.
  • Wird in allen modernen Browsern und in Node.js unterstützt.