Signatur
Beschreibung
Reflect.defineProperty() legt eine neue Eigenschaft direkt auf einem Objekt an oder ändert eine vorhandene. Dafür gibt man einen Eigenschafts-Deskriptor an, also ein Objekt mit value, writable, enumerable, configurable bzw. get/set. Die Methode funktioniert genauso wie Object.defineProperty().
Der wichtige Unterschied liegt im Rückgabewert: Object.defineProperty() gibt das Objekt zurück und wirft einen TypeError, wenn die Definition fehlschlägt, etwa bei einer nicht konfigurierbaren Eigenschaft oder einem nicht erweiterbaren Objekt. Reflect.defineProperty() gibt dagegen einfach true bei Erfolg und false bei Misserfolg zurück. Deshalb kann man den Erfolg mit einem normalen if prüfen und braucht kein try/catch.
Besonders nützlich ist die Methode in Proxy-Handlern: Die Falle defineProperty muss einen Wahrheitswert zurückgeben, und Reflect.defineProperty() liefert genau diesen Wert, wenn man an das Standardverhalten weiterleitet. Auch in Bibliotheken, die Objekte defensiv verändern, macht der boolesche Rückgabewert den Code übersichtlicher.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | object | Das Zielobjekt, auf dem die Eigenschaft definiert werden soll. Ist es kein Objekt, wird ein TypeError geworfen. |
|
| $propertyKey Pflicht | string|symbol | Name der Eigenschaft, die definiert oder geändert werden soll. Andere Werte werden in einen String umgewandelt. | |
| $attributes Pflicht | object | Eigenschafts-Deskriptor mit value, writable, get, set, enumerable und configurable. Fehlende Attribute gelten bei neuen Eigenschaften als false bzw. undefined. |
Rückgabewert
true, wenn die Eigenschaft erfolgreich definiert wurde, sonst false.Beispiele
Einfache Eigenschaft definieren und Erfolg prüfen
const config = {};
const ok = Reflect.defineProperty(config, 'version', {
value: '1.0.0',
writable: false,
enumerable: true,
configurable: false
});
console.log(ok);
console.log(config.version);
Fehlschlag ohne try/catch erkennen
const frozen = Object.freeze({ id: 42 });
if (!Reflect.defineProperty(frozen, 'name', { value: 'Test' })) {
console.log('Eigenschaft konnte nicht angelegt werden');
}
// Zum Vergleich: Object.defineProperty wirft
try {
Object.defineProperty(frozen, 'name', { value: 'Test' });
} catch (err) {
console.log(err.constructor.name);
}
Proxy-Falle mit Validierung
const user = {};
const guarded = new Proxy(user, {
defineProperty(target, key, descriptor) {
if (key.toString().startsWith('_')) {
console.log(`Private Eigenschaft ${String(key)} abgelehnt`);
return false;
}
// An Standardverhalten weiterleiten, liefert boolean
return Reflect.defineProperty(target, key, descriptor);
}
});
console.log(Reflect.defineProperty(guarded, 'name', { value: 'Anna', enumerable: true }));
console.log(Reflect.defineProperty(guarded, '_secret', { value: 'x' }));
console.log(Object.keys(user));
Getter als berechnete Eigenschaft
const rect = { width: 4, height: 3 };
Reflect.defineProperty(rect, 'area', {
get() {
return this.width * this.height;
},
enumerable: false,
configurable: true
});
rect.width = 10;
console.log(rect.area);
console.log(Object.keys(rect));
// Wichtig · Fallstricke
- Nicht jeder Fehler ergibt
false: Isttargetkein Objekt (z. B.nulloder ein primitiver Wert), wirft die Methode trotzdem einenTypeError. Das gilt auch für einen ungültigen Deskriptor, der zum Beispielvalueundgetgleichzeitig enthält. - Standardwerte beachten: Bei neuen Eigenschaften sind
writable,enumerableundconfigurablestandardmäßigfalse. Das ist anders als bei einer einfachen Zuweisung (obj.x = 1), bei der alle dreitruesind. - Eine nicht konfigurierbare Eigenschaft lässt sich nicht mehr umdefinieren oder löschen. Die einzige Ausnahme:
writabledarf vontrueauffalsegesetzt werden. - In Proxy-Fallen muss das Ergebnis die Invarianten des Zielobjekts einhalten. Andernfalls wirft die Engine einen
TypeError, auch wenn die Falletruezurückgibt. - Kompatibilität: Wird von allen modernen Browsern und von Node.js ab Version 6 unterstützt. Nicht verfügbar im Internet Explorer.