Start · Sprachen · JavaScript · Referenz · Reflect.preventExtensions()

Reflect.preventExtensions()

Methode

Verhindert, dass einem Objekt neue Eigenschaften hinzugefügt werden, und gibt als <code>boolean</code> zurück, ob das gelungen ist.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Reflect.preventExtensions(target)

Beschreibung

Reflect.preventExtensions() macht ein Objekt nicht erweiterbar: Danach lassen sich keine neuen Eigenschaften mehr hinzufügen. Bestehende Eigenschaften bleiben änderbar und löschbar, sofern ihre Deskriptoren das erlauben. Auch der Prototyp lässt sich danach nicht mehr ändern.

Im Unterschied zu Object.preventExtensions() gibt die Methode keinen Objektverweis zurück, sondern einen boolean. Er zeigt an, ob die Operation erfolgreich war. Das ist vor allem bei Proxys wichtig: Deren preventExtensions-Trap kann false zurückgeben, und Reflect.preventExtensions() reicht diesen Wert einfach weiter. Object.preventExtensions() würde in diesem Fall einen TypeError werfen.

Ein weiterer Unterschied: Übergibt man einen Primitivwert, wirft Reflect.preventExtensions() einen TypeError. Object.preventExtensions() gibt einen Primitivwert dagegen seit ES2015 einfach unverändert zurück.

Typischerweise nutzt man die Methode in Proxy-Traps, um das Standardverhalten weiterzuleiten, oder in Bibliothekscode, der Erfolg und Misserfolg ohne try...catch prüfen will.

Parameter

Name Typ Default Beschreibung
$target Pflicht object Das Zielobjekt, das nicht mehr erweiterbar sein soll. Ist es kein Objekt, wird ein TypeError geworfen.

Beispiele

Grundlegende Verwendung

const config = { debug: false };

console.log(Reflect.isExtensible(config));        // true
console.log(Reflect.preventExtensions(config));   // true
console.log(Reflect.isExtensible(config));        // false

// Bestehende Eigenschaften bleiben änderbar
config.debug = true;
// Neue Eigenschaften werden ignoriert (im strikten Modus: TypeError)
config.verbose = true;

console.log(config);
true true false { debug: true }

Unterschied zu Object.preventExtensions() bei Primitivwerten

console.log(Object.preventExtensions(42)); // 42

try {
  Reflect.preventExtensions(42);
} catch (err) {
  console.log(err.constructor.name); // TypeError
}
42 TypeError

Proxy-Trap mit Protokollierung und Weiterleitung

const target = { name: 'Server' };

const proxy = new Proxy(target, {
  preventExtensions(t) {
    console.log('preventExtensions aufgerufen');
    return Reflect.preventExtensions(t); // Standardverhalten weiterleiten
  }
});

const ok = Reflect.preventExtensions(proxy);
console.log(ok, Object.isExtensible(target));
preventExtensions aufgerufen true false

Erfolg ohne try...catch prüfen

const locked = new Proxy({}, {
  preventExtensions: () => false // lehnt das Sperren ab
});

if (!Reflect.preventExtensions(locked)) {
  console.log('Objekt konnte nicht gesperrt werden');
}

// Object.preventExtensions würde hier werfen:
try {
  Object.preventExtensions(locked);
} catch (err) {
  console.log('Object.preventExtensions:', err.name);
}
Objekt konnte nicht gesperrt werden Object.preventExtensions: TypeError

// Wichtig · Fallstricke

  • Nicht umkehrbar: Ein nicht erweiterbares Objekt lässt sich nie wieder erweiterbar machen.
  • Nur flach: Verschachtelte Objekte bleiben erweiterbar. Für tiefes Sperren muss man rekursiv vorgehen.
  • Schwächer als seal/freeze: Eigenschaften lassen sich weiterhin löschen und ändern. Für stärkeren Schutz gibt es Object.seal() und Object.freeze().
  • Stilles Scheitern: Außerhalb des strikten Modus werden Zuweisungen an neue Eigenschaften ohne Fehler ignoriert. Im strikten Modus wird ein TypeError geworfen.
  • Proxy-Invariante: Ein preventExtensions-Trap darf nur dann true zurückgeben, wenn das Zielobjekt danach tatsächlich nicht erweiterbar ist. Sonst wird ein TypeError geworfen.
  • Die Methode wird von allen modernen Browsern und von Node.js unterstützt, nicht aber vom Internet Explorer.