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

Object.getOwnPropertyDescriptors()

Methode

Gibt ein Objekt mit den Eigenschaftsdeskriptoren aller eigenen Eigenschaften (inklusive Symbole und nicht aufzählbarer Eigenschaften) eines Objekts zurück.

seit JavaScript ES2017 Kategorie: method-property

Signatur

Object.getOwnPropertyDescriptors(obj)

Beschreibung

Object.getOwnPropertyDescriptors() liefert für jede eigene Eigenschaft eines Objekts deren vollständigen Deskriptor. Dazu gehören auch nicht aufzählbare Eigenschaften und Eigenschaften mit Symbol-Schlüssel. Das Ergebnis ist ein einfaches Objekt: Die Schlüssel entsprechen den Eigenschaftsnamen, die Werte sind Deskriptor-Objekte wie bei Object.getOwnPropertyDescriptor().

Ein Datendeskriptor enthält value, writable, enumerable und configurable. Ein Zugriffsdeskriptor enthält get, set, enumerable und configurable. Geerbte Eigenschaften aus der Prototypkette werden nicht berücksichtigt.

Am häufigsten wird die Methode zusammen mit Object.defineProperties() oder Object.create() eingesetzt, um Objekte exakt zu kopieren. Anders als Object.assign() oder die Spread-Syntax übernimmt dieser Weg Getter und Setter als Funktionen, statt sie auszuwerten. Außerdem bleiben Attribute wie writable: false oder enumerable: false erhalten.

Parameter

Name Typ Default Beschreibung
$obj Pflicht any Das Objekt, dessen eigene Eigenschaftsdeskriptoren ausgelesen werden. Primitive Werte werden seit ES2015 in ein Objekt umgewandelt; bei null und undefined wird ein TypeError geworfen.

Rückgabewert

Typ
Object
Beschreibung
Ein Objekt mit einem Deskriptor für jede eigene Eigenschaft von obj. Hat obj keine eigenen Eigenschaften, ist es ein leeres Objekt {}.

Beispiele

Alle Deskriptoren eines Objekts auslesen

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

console.log(Object.getOwnPropertyDescriptors(user));
{ name: { value: 'Anna', writable: true, enumerable: true, configurable: true }, greeting: { get: [Function: get greeting], set: undefined, enumerable: true, configurable: true } }

Flache Kopie mit Gettern und Settern (statt Object.assign)

const source = {
  _temp: 20,
  get fahrenheit() { return this._temp * 9 / 5 + 32; },
  set fahrenheit(f) { this._temp = (f - 32) * 5 / 9; }
};

// Object.assign wertet den Getter aus – der Setter geht verloren
const naive = Object.assign({}, source);
console.log(Object.getOwnPropertyDescriptor(naive, 'fahrenheit'));

// Exakte Kopie: Getter und Setter bleiben Funktionen
const copy = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source));
copy.fahrenheit = 212;
console.log(copy._temp);
{ value: 68, writable: true, enumerable: true, configurable: true } 100

Klon mit gleichem Prototyp erzeugen

class Point {
  constructor(x, y) { this.x = x; this.y = y; }
  toString() { return `(${this.x}, ${this.y})`; }
}

const p = new Point(1, 2);
Object.defineProperty(p, 'id', { value: 42, enumerable: false });

const clone = Object.create(
  Object.getPrototypeOf(p),
  Object.getOwnPropertyDescriptors(p)
);

console.log(clone instanceof Point, String(clone), clone.id);
console.log(Object.keys(clone));
true (1, 2) 42 [ 'x', 'y' ]

Symbole und nicht aufzählbare Eigenschaften

const secret = Symbol('secret');
const obj = { [secret]: 'geheim' };
Object.defineProperty(obj, 'hidden', { value: 1 });

const descriptors = Object.getOwnPropertyDescriptors(obj);
console.log(Reflect.ownKeys(descriptors));
console.log(descriptors.hidden);
[ 'hidden', Symbol(secret) ] { value: 1, writable: false, enumerable: false, configurable: false }

// Wichtig · Fallstricke

  • Nur flach: Die Kopie per Object.defineProperties() ist eine flache Kopie. Verschachtelte Objekte werden weiterhin gemeinsam genutzt. Für tiefe Kopien eignet sich structuredClone(); das übernimmt aber weder Getter noch Setter noch Prototypen.
  • Private Klassenfelder (#feld) tauchen nicht auf und werden deshalb auch nicht kopiert. Methoden, die auf private Felder zugreifen, werfen beim Klon einen TypeError.
  • Getter-Bindung: Kopierte Getter und Setter verwenden this dynamisch, beziehen sich also auf das neue Objekt und nicht auf das Original.
  • Proxies: Bei einem Proxy werden die Traps ownKeys und getOwnPropertyDescriptor ausgelöst. Liefert der Trap undefined, fehlt die Eigenschaft im Ergebnis.
  • Bei null oder undefined als Argument wird ein TypeError geworfen.
  • Kompatibilität: ES2017, wird von allen modernen Browsern und von Node.js ab Version 7 unterstützt. Der Internet Explorer unterstützt die Methode nicht; dort lässt sie sich mit Reflect.ownKeys() und Object.getOwnPropertyDescriptor() nachbilden.