Start · Sprachen · JavaScript · Referenz · Proxy.revocable()

Proxy.revocable()

Methode

Erstellt einen widerrufbaren Proxy und gibt ein Objekt <code>{ proxy, revoke }</code> zurück, mit dessen <code>revoke()</code> der Proxy dauerhaft deaktiviert werden kann.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Proxy.revocable(target, handler)

Beschreibung

Proxy.revocable() funktioniert wie new Proxy(target, handler), gibt aber zusätzlich eine Funktion revoke zurück. Sobald revoke() aufgerufen wurde, wirft jede Operation auf dem Proxy (Lesen, Schreiben, in, delete, Funktionsaufruf, typeof ausgenommen) einen TypeError.

Typische Einsatzfälle sind zeitlich begrenzter Zugriff auf ein Objekt, etwa wenn Sie einem Plugin, einer Drittanbieter-Bibliothek oder einem Callback Zugriff auf Daten geben und diesen später wieder entziehen wollen (Capability-Muster, „Membranen“). Ebenso nützlich ist es, um versehentliche Nutzung nach dem Ende einer Sitzung oder Transaktion zu erkennen.

Nach dem Widerruf löst sich der Proxy von Ziel und Handler, sodass diese – sofern sonst nicht mehr referenziert – vom Garbage Collector freigegeben werden können. Ein widerrufener Proxy lässt sich nicht wieder aktivieren; bei Bedarf muss ein neuer erzeugt werden.

Parameter

Name Typ Default Beschreibung
$target Pflicht object | Function Das Zielobjekt, das der Proxy umhüllt. Jedes Objekt ist erlaubt, auch Arrays, Funktionen oder ein anderer Proxy. Primitive Werte führen zu einem TypeError.
$handler Pflicht object Objekt mit Trap-Funktionen (z. B. get, set, has, apply). Ein leeres Objekt {} ergibt einen reinen Durchreich-Proxy.

Rückgabewert

Typ
{ proxy: Proxy, revoke: () => void }
Beschreibung
Ein einfaches Objekt mit zwei Eigenschaften: proxy – der neu erzeugte Proxy, und revoke – eine parameterlose Funktion, die den Proxy dauerhaft widerruft. Mehrfaches Aufrufen von revoke() ist unschädlich.

Beispiele

Grundlegende Verwendung und Widerruf

const { proxy, revoke } = Proxy.revocable({ name: 'Ada' }, {
  get: (target, prop) => `Wert: ${Reflect.get(target, prop)}`
});

console.log(proxy.name);

revoke();

try {
  console.log(proxy.name);
} catch (err) {
  console.log(err.constructor.name);
}

console.log(typeof proxy); // typeof funktioniert weiterhin
Wert: Ada TypeError object

Zeitlich begrenzter Zugriff für ein Plugin

const config = { apiKey: 'geheim-123', endpoint: 'https://api.example.com' };

const runPlugin = async (plugin) => {
  const { proxy, revoke } = Proxy.revocable(config, {
    set: () => { throw new TypeError('Konfiguration ist schreibgeschützt'); }
  });
  try {
    await plugin(proxy);
  } finally {
    revoke(); // Plugin verliert nach Abschluss jeden Zugriff
  }
};

let gespeicherteReferenz;
await runPlugin(async (cfg) => {
  console.log('Plugin nutzt', cfg.endpoint);
  gespeicherteReferenz = cfg; // Plugin versucht, die Referenz zu behalten
});

try {
  gespeicherteReferenz.apiKey;
} catch {
  console.log('Zugriff nach Ende verweigert');
}
Plugin nutzt https://api.example.com Zugriff nach Ende verweigert

Widerrufbare Funktion (Einmal-Callback)

const once = (fn) => {
  const { proxy, revoke } = Proxy.revocable(fn, {
    apply: (target, thisArg, args) => {
      revoke(); // nach dem ersten Aufruf deaktivieren
      return Reflect.apply(target, thisArg, args);
    }
  });
  return proxy;
};

const greet = once((name) => `Hallo, ${name}!`);
console.log(greet('Welt'));

try {
  greet('nochmal');
} catch (err) {
  console.log('Zweiter Aufruf:', err instanceof TypeError);
}
Hallo, Welt! Zweiter Aufruf: true

// Wichtig · Fallstricke

  • Nicht umkehrbar: Ein widerrufener Proxy lässt sich nicht wieder aktivieren. Selbst harmlose Operationen wie Object.keys(proxy), 'x' in proxy oder Array.isArray(proxy) werfen danach einen TypeError. Nur typeof proxy funktioniert weiterhin.
  • Kein Status abfragbar: Es gibt keine eingebaute Möglichkeit, festzustellen, ob ein Proxy bereits widerrufen wurde. Führen Sie bei Bedarf ein eigenes Flag oder fangen Sie den TypeError ab.
  • Kein Konstruktor: new Proxy.revocable() wirft einen TypeError. Rufen Sie die Methode direkt auf.
  • Nur der Proxy wird gesperrt: Wer eine direkte Referenz auf target besitzt, kann weiterhin zugreifen. Für echte Zugriffskontrolle darf das Ziel nicht nach außen gelangen – auch nicht über Rückgabewerte verschachtelter Objekte (dafür ggf. rekursiv Proxys erzeugen, sog. „Membranen“).
  • Kompatibilität: Seit ES2015 in allen modernen Browsern und Node.js 6+ verfügbar; Proxys lassen sich nicht polyfillen (kein Internet Explorer).