Signatur
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
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));
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);
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));
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);
// Wichtig · Fallstricke
- Nur flach: Die Kopie per
Object.defineProperties()ist eine flache Kopie. Verschachtelte Objekte werden weiterhin gemeinsam genutzt. Für tiefe Kopien eignet sichstructuredClone(); 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 einenTypeError. - Getter-Bindung: Kopierte Getter und Setter verwenden
thisdynamisch, beziehen sich also auf das neue Objekt und nicht auf das Original. - Proxies: Bei einem Proxy werden die Traps
ownKeysundgetOwnPropertyDescriptorausgelöst. Liefert der Trapundefined, fehlt die Eigenschaft im Ergebnis. - Bei
nulloderundefinedals Argument wird einTypeErrorgeworfen. - 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()undObject.getOwnPropertyDescriptor()nachbilden.