Signatur
Beschreibung
Mit get definierst du eine Accessor-Eigenschaft: Von außen sieht sie aus wie eine normale Eigenschaft (obj.prop), beim Lesen wird aber eine Funktion ausgeführt. Ihr Rückgabewert ist der gelesene Wert. So kannst du Werte bei Bedarf berechnen, abgeleitete Daten liefern (z. B. fullName aus Vor- und Nachname) oder interne Zustände nur lesbar nach außen geben.
Getter gibt es in Objektliteralen, in Klassen (als Instanz-Getter auf dem Prototyp oder als static get) und mit berechneten Namen (get [key]()). Die Getter-Funktion nimmt keine Parameter an. Innerhalb des Getters zeigt this auf das Objekt, über das zugegriffen wurde.
Häufig kombiniert man get mit einem passenden set für dieselbe Eigenschaft. Ohne Setter ist die Eigenschaft praktisch schreibgeschützt: Zuweisungen werden im Sloppy Mode stillschweigend ignoriert und werfen im Strict Mode (und damit in Klassen und Modulen) einen TypeError.
Auf bestehenden Objekten legst du Getter nachträglich mit Object.defineProperty() an. Auslesen lässt sich die Getter-Funktion über Object.getOwnPropertyDescriptor(obj, 'prop').get.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $prop Pflicht | string | Bezeichner | Name der Eigenschaft, die an die Getter-Funktion gebunden wird. | |
| $expression | any (wird zu string | symbol umgewandelt) | Seit ES2015: ein berechneter Eigenschaftsname in eckigen Klammern, z. B. get [Symbol.toStringTag](). |
Rückgabewert
return ergibt sich undefined.Beispiele
Berechnete Eigenschaft im Objektliteral
const user = {
firstName: 'Anna',
lastName: 'Schmidt',
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
};
console.log(user.fullName);
user.lastName = 'Meier';
console.log(user.fullName); // wird bei jedem Zugriff neu berechnet
Nur-lesbarer Zustand in einer Klasse mit privatem Feld
class Warenkorb {
#artikel = [];
add(name, preis) {
this.#artikel.push({ name, preis });
}
get summe() {
return this.#artikel.reduce((s, a) => s + a.preis, 0);
}
get anzahl() {
return this.#artikel.length;
}
}
const korb = new Warenkorb();
korb.add('Buch', 19.9);
korb.add('Stift', 2.5);
console.log(korb.anzahl, korb.summe.toFixed(2));
try {
korb.summe = 0; // Klassen laufen im Strict Mode
} catch (e) {
console.log(e.constructor.name);
}
Lazy Getter mit Caching und berechnetem Namen
const key = 'config';
const app = {
get [key]() {
console.log('Lade Konfiguration …');
const value = { theme: 'dark', lang: 'de' };
// Getter durch Dateneigenschaft ersetzen -> nur einmal berechnen
Object.defineProperty(this, key, { value, writable: false });
return value;
}
};
console.log(app.config.theme);
console.log(app.config.lang); // kein erneutes Laden
Getter nachträglich mit Object.defineProperty
const temp = { celsius: 21 };
Object.defineProperty(temp, 'fahrenheit', {
get() {
return this.celsius * 9 / 5 + 32;
},
enumerable: true,
configurable: true
});
console.log(temp.fahrenheit);
console.log(typeof Object.getOwnPropertyDescriptor(temp, 'fahrenheit').get);
// Wichtig · Fallstricke
- Keine Parameter: Ein Getter mit Parametern ist ein
SyntaxError. - Endlosrekursion: Liest der Getter seine eigene Eigenschaft (
get name() { return this.name; }), entsteht einRangeError: Maximum call stack size exceeded. Speichere den Wert in einer anderen Eigenschaft, z. B. einem privaten Feld#name. - Ohne Setter schreibgeschützt: Zuweisungen werden im Sloppy Mode ignoriert und werfen im Strict Mode einen
TypeError. - Performance: Der Getter läuft bei jedem Zugriff. Aufwendige Berechnungen solltest du zwischenspeichern (siehe Lazy-Getter-Beispiel) oder als Methode anbieten, damit Aufrufer die Kosten erkennen.
- Klassen-Getter liegen auf dem Prototyp und sind nicht aufzählbar. Deshalb tauchen sie nicht in
Object.keys(),JSON.stringify()oder beim Spread{...obj}auf. Getter in Objektliteralen sind dagegen aufzählbar, und beim Spread oder beiObject.assign()wird nur ihr aktueller Wert kopiert, nicht der Getter selbst. - Im selben Objektliteral kann ein Name nicht gleichzeitig Getter und Dateneigenschaft sein. Die spätere Definition überschreibt die frühere.
- Kompatibilität: In allen modernen Browsern und in Node.js unterstützt. Das veraltete
__defineGetter__()solltest du nicht mehr verwenden.