Signatur
Beschreibung
Die Methode handler.getPrototypeOf() ist eine Falle (Trap) im Handler-Objekt eines Proxy. Sie wird immer dann aufgerufen, wenn die JavaScript-Engine den Prototyp des Proxys ermitteln will, also bei der internen Operation [[GetPrototypeOf]]. Mit ihr lässt sich steuern, welchen Prototyp ein Objekt nach außen vorgibt zu haben.
Die Falle wird unter anderem ausgelöst durch:
Object.getPrototypeOf(proxy)undReflect.getPrototypeOf(proxy)Object.prototype.isPrototypeOf(), z. B.Array.prototype.isPrototypeOf(proxy)- den Operator
instanceof(bei der Prototypkette des linken Operanden) - den Accessor
proxy.__proto__
Typische Einsatzzwecke sind das Maskieren oder Verschleiern des echten Typs, das Protokollieren von Prototyp-Abfragen, Sandboxing sowie das Nachbilden von Vererbung bei Wrapper-Objekten. Wird die Falle nicht definiert, leitet der Proxy die Operation unverändert an das Zielobjekt weiter – dasselbe erreicht man explizit mit Reflect.getPrototypeOf(target).
Die Rückgabe muss ein Objekt oder null sein. Außerdem gilt eine Invariante: Ist das Zielobjekt nicht erweiterbar (Object.isExtensible(target) === false), muss die Falle genau den echten Prototyp des Ziels zurückgeben. Sonst wirft die Engine einen TypeError.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | object | Das Zielobjekt, das der Proxy umhüllt. Der Handler-Kontext this ist an das Handler-Objekt gebunden. |
Rückgabewert
null. Andere Werte (z. B. Zahlen, Strings, undefined) führen zu einem TypeError.Beispiele
Prototyp-Abfragen protokollieren und durchreichen
const user = { name: 'Anna' };
const proxy = new Proxy(user, {
getPrototypeOf(target) {
console.log('Prototyp wird abgefragt');
return Reflect.getPrototypeOf(target);
}
});
console.log(Object.getPrototypeOf(proxy) === Object.prototype);
Einen anderen Typ vortäuschen (instanceof)
class Admin {}
const plain = { role: 'admin' };
const fakeAdmin = new Proxy(plain, {
getPrototypeOf() {
return Admin.prototype;
}
});
console.log(fakeAdmin instanceof Admin);
console.log(Admin.prototype.isPrototypeOf(fakeAdmin));
console.log(Object.getPrototypeOf(plain) === Object.prototype);
Prototyp verbergen (Sandboxing)
const secret = new Map([['key', 42]]);
const hidden = new Proxy(secret, {
getPrototypeOf() {
return null; // Prototypkette nach außen verschleiern
}
});
console.log(Object.getPrototypeOf(hidden));
console.log(hidden instanceof Map);
Invariante verletzt: nicht erweiterbares Ziel
const target = Object.preventExtensions({});
const proxy = new Proxy(target, {
getPrototypeOf() {
return Array.prototype; // weicht vom echten Prototyp ab
}
});
try {
Object.getPrototypeOf(proxy);
} catch (err) {
console.log(err instanceof TypeError);
}
// Wichtig · Fallstricke
- Rückgabetyp: Nur ein Objekt oder
nullist erlaubt, alles andere wirft einenTypeError. - Invariante: Ist das Ziel nicht erweiterbar (
Object.preventExtensions,Object.seal,Object.freeze), muss die FalleObject.getPrototypeOf(target)zurückgeben. - Nur Schein: Die Falle ändert nur, was Abfragen melden. Das Nachschlagen von Eigenschaften (
proxy.foo) läuft weiterhin über dieget-Falle bzw. die echte Prototypkette des Ziels. Wer die Vererbung wirklich umbiegen will, muss zusätzlichgetundhasabfangen. - instanceof: Hat die Klasse eine eigene
Symbol.hasInstance-Methode, wird diese statt der Prototypkette verwendet, und die Falle wird dann eventuell gar nicht aufgerufen. - Performance: Häufige Prototyp-Abfragen über Proxys sind deutlich langsamer als bei normalen Objekten. In heißen Codepfaden sollte man das vermeiden.
- Kompatibilität: Wird von allen modernen Browsern und von Node.js (ab 6) unterstützt. Im Internet Explorer gibt es das nicht, und Proxys lassen sich nicht per Polyfill nachrüsten.