Signatur
Beschreibung
__defineSetter__() legt auf dem Objekt, auf dem die Methode aufgerufen wird, eine Accessor-Eigenschaft an (oder ändert eine vorhandene). Jede spätere Zuweisung wie obj.prop = wert ruft dann die übergebene Funktion auf. Der zugewiesene Wert wird ihr als einziges Argument übergeben, this zeigt auf das Objekt.
Die Methode stammt aus der Zeit vor ES5. Damals gab es noch kein Object.defineProperty() und keine set-Syntax in Objektliteralen. Heute ist sie nur noch im Anhang B der Spezifikation (Legacy-Features für Web-Browser) festgehalten und gilt als veraltet. Neuer Code sollte stattdessen die set-Syntax in Objektliteralen und Klassen oder Object.defineProperty() verwenden.
Intern entspricht der Aufruf ungefähr Object.defineProperty(obj, prop, { set: func, enumerable: true, configurable: true }). Ein bereits vorhandener Getter derselben Eigenschaft bleibt dabei erhalten. War die Eigenschaft dagegen eine Dateneigenschaft, geht ihr bisheriger Wert verloren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $prop Pflicht | string | symbol | Name der Eigenschaft, an die der Setter gebunden wird. Andere Werte werden in einen Eigenschaftsschlüssel umgewandelt. | |
| $func Pflicht | Function | Funktion, die bei einer Zuweisung an prop aufgerufen wird. Sie bekommt den zugewiesenen Wert als Argument (function (val) { … }). Ist func nicht aufrufbar, wird ein TypeError ausgelöst. |
Rückgabewert
undefined). Das Objekt selbst wird verändert.Beispiele
Setter mit Validierung (Legacy-Stil)
const konto = { _saldo: 0 };
konto.__defineSetter__('saldo', function (wert) {
if (typeof wert !== 'number' || Number.isNaN(wert)) {
throw new TypeError('Saldo muss eine Zahl sein');
}
this._saldo = Math.round(wert * 100) / 100;
});
konto.__defineGetter__('saldo', function () {
return this._saldo;
});
konto.saldo = 19.999;
console.log(konto.saldo);
try {
konto.saldo = 'viel';
} catch (e) {
console.log(e.message);
}
Moderne Entsprechung mit set-Syntax und Object.defineProperty()
// 1. Setter direkt im Objektliteral
const nutzer = {
_name: '',
set name(wert) {
this._name = String(wert).trim();
},
get name() {
return this._name;
}
};
nutzer.name = ' Anna ';
console.log(nutzer.name);
// 2. Setter nachträglich hinzufügen
const protokoll = [];
const config = {};
Object.defineProperty(config, 'modus', {
set(wert) { protokoll.push(`modus -> ${wert}`); },
enumerable: true,
configurable: true
});
config.modus = 'dark';
console.log(protokoll);
Setter prüfen und Nur-Setter-Falle
const obj = {};
obj.__defineSetter__('x', (v) => console.log('gesetzt:', v));
obj.x = 42;
// Ohne Getter liefert das Lesen undefined
console.log(obj.x);
// Setter wieder auslesen
console.log(typeof obj.__lookupSetter__('x'));
console.log(Object.getOwnPropertyDescriptor(obj, 'x'));
// Wichtig · Fallstricke
- Veraltet: Die Methode ist nur in Anhang B von ECMAScript spezifiziert. Sie funktioniert in allen gängigen Browsern und in Node.js, sollte in neuem Code aber durch die
set-Syntax oderObject.defineProperty()ersetzt werden. - Nicht überall verfügbar: Objekte ohne Prototyp (
Object.create(null)) erben die Methode nicht. Ein Aufruf wirft dort einenTypeError. Auch manche Linter- und Sicherheitsrichtlinien verbieten ihre Nutzung. - Nur Setter, kein Getter: Wird kein Getter definiert, liefert das Lesen der Eigenschaft
undefined. Der vorherige Wert einer Dateneigenschaft wird überschrieben. - Endlosrekursion: Weist der Setter selbst
this.propzu (dieselbe Eigenschaft), ruft er sich endlos selbst auf und es kommt zu einemRangeError. Speichere den Wert daher in einem anderen Feld (z. B._prop) oder in einer Closure. - Arrow-Funktionen: Sie haben kein eigenes
this. Wenn der Setter auf das Objekt zugreifen soll, verwende eine normalefunction. - Ist die Eigenschaft nicht konfigurierbar (z. B. nach
Object.freeze()) oder das Objekt nicht erweiterbar, wird einTypeErrorausgelöst.