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

Reflect.getOwnPropertyDescriptor()

Methode

Gibt den Eigenschafts-Deskriptor einer eigenen Eigenschaft eines Objekts zurück oder <code>undefined</code>, wenn die Eigenschaft nicht existiert.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Beschreibung

Reflect.getOwnPropertyDescriptor() liest den vollständigen Deskriptor einer eigenen (nicht geerbten) Eigenschaft aus. Das Ergebnis ist ein Objekt mit den Feldern value, writable, enumerable und configurable (Daten-Eigenschaft) bzw. get, set, enumerable und configurable (Accessor-Eigenschaft).

Die Methode verhält sich fast genauso wie Object.getOwnPropertyDescriptor(). Der wichtige Unterschied: Ist target kein Objekt (etwa ein String oder eine Zahl), wirft Reflect.getOwnPropertyDescriptor() einen TypeError, während Object.getOwnPropertyDescriptor() den primitiven Wert seit ES2015 stillschweigend in ein Objekt umwandelt.

Ihr Haupteinsatzgebiet ist die Arbeit mit Proxy: In der Trap getOwnPropertyDescriptor leitet man mit Reflect.getOwnPropertyDescriptor(target, prop) das Standardverhalten sauber an das Zielobjekt weiter. Außerdem eignet sie sich für Metaprogrammierung, z. B. um zu prüfen, ob eine Eigenschaft schreibgeschützt ist oder einen Getter besitzt, bevor man sie kopiert oder verändert.

Parameter

Name Typ Default Beschreibung
$target Pflicht object Das Zielobjekt, auf dem die eigene Eigenschaft gesucht wird. Muss ein Objekt sein, sonst wird ein TypeError geworfen.
$propertyKey Pflicht string|symbol Name oder Symbol der Eigenschaft. Andere Werte werden in einen String umgewandelt.

Rückgabewert

Typ
PropertyDescriptor|undefined
Beschreibung
Ein Deskriptor-Objekt ({ value, writable, enumerable, configurable } oder { get, set, enumerable, configurable }), wenn die Eigenschaft als eigene Eigenschaft existiert, sonst undefined.

Beispiele

Deskriptor einer Daten- und einer Accessor-Eigenschaft lesen

const user = {
  name: 'Anna',
  get greeting() {
    return `Hallo ${this.name}`;
  }
};

console.log(Reflect.getOwnPropertyDescriptor(user, 'name'));
console.log(Reflect.getOwnPropertyDescriptor(user, 'greeting'));
console.log(Reflect.getOwnPropertyDescriptor(user, 'toString')); // geerbt
{ value: 'Anna', writable: true, enumerable: true, configurable: true } { get: [Function: get greeting], set: undefined, enumerable: true, configurable: true } undefined

Prüfen, ob eine Eigenschaft schreibgeschützt ist

const config = {};
Object.defineProperty(config, 'apiUrl', {
  value: 'https://api.example.com',
  writable: false,
  enumerable: true,
  configurable: false
});

const isReadOnly = (obj, key) => {
  const desc = Reflect.getOwnPropertyDescriptor(obj, key);
  if (!desc) return false;
  return 'value' in desc ? !desc.writable : desc.set === undefined;
};

console.log(isReadOnly(config, 'apiUrl'));
console.log(isReadOnly({ port: 8080 }, 'port'));
true false

Proxy-Trap: private Felder verbergen

const account = { owner: 'Ben', _secret: 'pin-1234' };

const safe = new Proxy(account, {
  getOwnPropertyDescriptor(target, prop) {
    if (typeof prop === 'string' && prop.startsWith('_')) {
      return undefined; // Eigenschaft wirkt nicht vorhanden
    }
    return Reflect.getOwnPropertyDescriptor(target, prop);
  }
});

console.log(Object.getOwnPropertyDescriptor(safe, 'owner')?.value);
console.log(Object.getOwnPropertyDescriptor(safe, '_secret'));
Ben undefined

Unterschied zu Object.getOwnPropertyDescriptor bei Primitiven

console.log(Object.getOwnPropertyDescriptor('abc', 'length'));

try {
  Reflect.getOwnPropertyDescriptor('abc', 'length');
} catch (err) {
  console.log(err.constructor.name);
}
{ value: 3, writable: false, enumerable: false, configurable: false } TypeError

// Wichtig · Fallstricke

  • Nur eigene Eigenschaften: Geerbte Eigenschaften aus der Prototypkette liefern undefined. Um sie zu finden, muss man die Kette mit Reflect.getPrototypeOf() selbst durchlaufen.
  • Kein Objekt → TypeError: Anders als Object.getOwnPropertyDescriptor() werden Primitive nicht umgewandelt. Das ist gewollt und macht Fehler früher sichtbar.
  • Proxy-Invarianten: Eine getOwnPropertyDescriptor-Trap darf eine nicht-konfigurierbare Eigenschaft des Ziels nicht als fehlend melden und auch keine Eigenschaft auf einem nicht-erweiterbaren Ziel erfinden. Bei Verstoß wirft die Engine einen TypeError.
  • Der zurückgegebene Deskriptor ist eine Kopie; Änderungen daran wirken sich nicht auf das Objekt aus. Zum Setzen dient Reflect.defineProperty().
  • Kompatibilität: in allen modernen Browsern und seit Node.js 6 verfügbar; nicht im Internet Explorer.