Signatur
Beschreibung
handler.get() ist die wohl am häufigsten genutzte Falle eines Proxy. Sie wird jedes Mal aufgerufen, wenn eine Eigenschaft des Proxys gelesen wird. Dazu zählen Punkt- und Klammerschreibweise (proxy.x, proxy[key]), Destrukturierung (const { x } = proxy), Reflect.get() und auch Lesezugriffe über die Prototypkette, wenn der Proxy als Prototyp eines anderen Objekts dient.
Typische Anwendungsfälle sind Standardwerte für fehlende Eigenschaften, Protokollierung und Debugging, Validierung (z. B. einen Fehler bei unbekannten Schlüsseln werfen), negative Array-Indizes, Lazy Loading sowie reaktive Systeme, die Abhängigkeiten beim Lesen erfassen (wie in Vue 3).
Der Rückgabewert der Falle ist das Ergebnis des Zugriffs. Um das Standardverhalten weiterzuleiten, solltest du Reflect.get(target, property, receiver) verwenden statt target[property], denn nur so werden Getter mit dem richtigen this (dem receiver) ausgeführt.
Die Falle muss bestimmte Invarianten einhalten: Ist eine Eigenschaft des Ziels nicht konfigurierbar und nicht beschreibbar, muss genau ihr Wert zurückgegeben werden. Ist sie eine nicht konfigurierbare Accessor-Eigenschaft ohne Getter, muss undefined zurückgegeben werden. Bei einem Verstoß wirft die Engine einen TypeError.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | object | Das Zielobjekt, das der Proxy umhüllt. | |
| $property Pflicht | string | symbol | Name der gelesenen Eigenschaft. Zahlen-Indizes kommen als String an (z. B. "0"), Symbole bleiben Symbole. |
|
| $receiver Pflicht | object | Das Objekt, auf dem der Zugriff ursprünglich erfolgte – meist der Proxy selbst, bei Vererbung aber das erbende Objekt. Wird als this für Getter benötigt. |
Rückgabewert
Beispiele
Standardwert für fehlende Eigenschaften
const config = { host: 'localhost' };
const withDefaults = new Proxy(config, {
get(target, prop, receiver) {
// Existiert die Eigenschaft, normal weiterleiten
if (prop in target) {
return Reflect.get(target, prop, receiver);
}
return `(nicht gesetzt: ${String(prop)})`;
}
});
console.log(withDefaults.host);
console.log(withDefaults.port);
Negative Array-Indizes wie in Python
const negativeArray = (arr) => new Proxy(arr, {
get(target, prop, receiver) {
// Indizes kommen als String an
if (typeof prop === 'string' && /^-\d+$/.test(prop)) {
prop = String(target.length + Number(prop));
}
return Reflect.get(target, prop, receiver);
}
});
const farben = negativeArray(['rot', 'grün', 'blau']);
console.log(farben[-1]);
console.log(farben[-3]);
console.log(farben.length);
Strenges Objekt: Tippfehler sofort erkennen
const strict = (obj) => new Proxy(obj, {
get(target, prop, receiver) {
// Symbole (z. B. Symbol.toPrimitive) durchlassen
if (typeof prop === 'symbol' || prop in target) {
return Reflect.get(target, prop, receiver);
}
throw new ReferenceError(`Unbekannte Eigenschaft: "${prop}"`);
}
});
const user = strict({ name: 'Anna', role: 'admin' });
console.log(user.name);
try {
console.log(user.rolle);
} catch (err) {
console.error(err.message);
}
Warum receiver wichtig ist: Getter mit this
const person = {
_name: 'Ben',
get name() { return this._name.toUpperCase(); }
};
const proxy = new Proxy(person, {
get(target, prop, receiver) {
console.log(`Lese ${String(prop)}`);
return Reflect.get(target, prop, receiver);
}
});
// Durch receiver läuft auch this._name über den Proxy
console.log(proxy.name);
// Wichtig · Fallstricke
- Invarianten: Für nicht konfigurierbare, nicht beschreibbare Dateneigenschaften des Ziels (z. B. nach
Object.freeze()) muss der echte Wert zurückgegeben werden, sonst folgt einTypeError. Reflect.getstatttarget[prop]: Mittarget[prop]laufen Getter mitthis === target, dann greifen verschachtelte Zugriffe nicht mehr auf die Falle zurück. Das führt z. B. bei Vererbung oder reaktiven Systemen zu schwer auffindbaren Fehlern.- Eigenschaftsnamen sind Strings oder Symbole:
proxy[0]kommt als"0"an. Außerdem fragen Engines,console.log, Template-Strings undawaitinterne Symbole bzw. Schlüssel ab (Symbol.toPrimitive,Symbol.iterator,then). Eine Falle, die bei unbekannten Schlüsseln einen Fehler wirft, kann deshalb unerwartet auslösen. Symbole undthensolltest du gezielt durchlassen. - Interne Slots: Proxys um
Map,Set,Dateoder DOM-Objekte scheitern bei Methodenaufrufen (TypeError: incompatible receiver), weilthisder Proxy ist. Abhilfe: Funktionen in der Falle mitvalue.bind(target)zurückgeben. - Leistung: Jeder Lesezugriff ruft eine Funktion auf. In heißen Schleifen ist das deutlich langsamer als ein direkter Zugriff.
- Kompatibilität: Wird von allen modernen Browsern und Node.js 6+ unterstützt. Ein Polyfill ist nicht möglich, Internet Explorer wird nicht unterstützt.