Signatur
Beschreibung
Die Methode isExtensible() im Handler-Objekt eines Proxy wird aufgerufen, sobald jemand fragt, ob dem Proxy noch neue Eigenschaften hinzugefügt werden können. Das passiert bei Object.isExtensible(proxy), Reflect.isExtensible(proxy) und indirekt auch bei Object.isFrozen() und Object.isSealed().
Nützlich ist die Trap vor allem für Protokollierung, Debugging und Zugriffsüberwachung: Man sieht, wann und wie oft Code die Erweiterbarkeit eines Objekts prüft. Den Rückgabewert frei verändern kann man aber nicht. Die Sprachspezifikation schreibt eine strenge Invariante vor: Das Ergebnis muss mit Object.isExtensible(target) übereinstimmen.
In der Praxis leitet man daher fast immer an Reflect.isExtensible(target) weiter und ergänzt davor oder danach eigene Logik. Wer die Erweiterbarkeit wirklich ändern will, muss das Zielobjekt selbst anpassen, zum Beispiel mit Object.preventExtensions(target), oder zusätzlich die Trap preventExtensions nutzen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | object | Das Zielobjekt des Proxys (das ursprüngliche Objekt, nicht der Proxy selbst). |
Rückgabewert
Object.isExtensible(target) sein, sonst wird ein TypeError ausgelöst.Beispiele
Prüfungen der Erweiterbarkeit protokollieren
const config = { debug: true };
const proxy = new Proxy(config, {
isExtensible(target) {
console.log('Erweiterbarkeit wird geprüft');
return Reflect.isExtensible(target);
}
});
console.log(Object.isExtensible(proxy));
Object.preventExtensions(config);
console.log(Reflect.isExtensible(proxy));
Invariante verletzt: TypeError
const proxy = new Proxy({}, {
// Das Ziel ist erweiterbar, die Trap behauptet das Gegenteil
isExtensible: () => false
});
try {
Object.isExtensible(proxy);
} catch (err) {
console.log(err instanceof TypeError, err.message);
}
Zugriffe zählen, zum Beispiel für Tests
const createCountingProxy = (obj) => {
const stats = { isExtensibleCalls: 0 };
const proxy = new Proxy(obj, {
isExtensible(target) {
stats.isExtensibleCalls++;
return Reflect.isExtensible(target);
}
});
return { proxy, stats };
};
const { proxy, stats } = createCountingProxy({ a: 1 });
Object.isExtensible(proxy);
Object.isFrozen(proxy); // löst die Trap ebenfalls aus
console.log(stats.isExtensibleCalls);
// Wichtig · Fallstricke
- Invariante:
Object.isExtensible(proxy)muss immer denselben Wert liefern wieObject.isExtensible(target). Bei einer Abweichung wird einTypeErrorausgelöst. Die Trap kann das Ergebnis also nicht vortäuschen. - Fehlt die Trap, wird die Operation direkt an das Zielobjekt weitergereicht.
Object.isFrozen()undObject.isSealed()rufen die Trap ebenfalls auf. Das kann in Zählern oder Protokollen zu unerwarteten zusätzlichen Aufrufen führen.- Innerhalb der Trap bezeichnet
thisdas Handler-Objekt, nicht den Proxy. - Der genaue Wortlaut der Fehlermeldung hängt von der JavaScript-Engine ab. Die Ausgabe im Beispiel stammt aus V8 (Chrome, Node.js).
- Wird von allen modernen Browsern und von Node.js ab Version 6 unterstützt. Der Internet Explorer unterstützt die Trap nicht, und sie lässt sich auch nicht durch ein Polyfill nachrüsten.