[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Guide/Meta_programming [Back]  [Original]

Metaprogrammierung - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

Metaprogrammierung

Die Objekte Proxy und Reflect ermglichen es Ihnen, fundamentale Sprachoperationen (z. B. Eigenschaftenabfrage, Zuweisung, Aufzhlung, Funktionsaufruf usw.) abzufangen und benutzerdefinierte Verhaltensweisen zu definieren. Mit Hilfe dieser beiden Objekte sind Sie in der Lage, auf der Metaebene von JavaScript zu programmieren.

In diesem Artikel

Proxies

Proxy-Objekte erlauben es Ihnen, bestimmte Operationen abzufangen und benutzerdefinierte Verhaltensweisen zu implementieren.

Zum Beispiel beim Abrufen einer Eigenschaft eines Objekts:

js
const handler = {
  get(target, name) {
    return name in target ? target[name] : 42;
  },
};

const p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 42

Das Proxy-Objekt definiert ein target (hier ein leeres Objekt) und ein handler-Objekt, in dem eine get-Falle (trap) implementiert ist. Hierbei wird ein proxied Objekt nicht undefined zurckgeben, wenn undefinierte Eigenschaften abgefragt werden, sondern stattdessen die Zahl 42.

Zustzliche Beispiele sind auf der Proxy-Referenzseite verfgbar.

Terminologie

Die folgenden Begriffe werden verwendet, wenn ber die Funktionalitt von Proxies gesprochen wird.

handler

Platzhalterobjekt, das Fallen enthlt.

Fallen (traps)

Die Methoden, die den Zugriff auf Eigenschaften bereitstellen. (Dies ist analog zum Konzept der Fallen in Betriebssystemen.)

Ziel (target)

Objekt, das vom Proxy virtualisiert wird. Es wird hufig als Speicherungshintergrund fr den Proxy verwendet. Invarianten (Semantiken, die unverndert bleiben) in Bezug auf die Nichterweiterbarkeit von Objekten oder nicht konfigurierbare Eigenschaften werden gegen das Ziel verifiziert.

Invarianten

Semantiken, die bei der Implementierung benutzerdefinierter Operationen unverndert bleiben, werden als Invarianten bezeichnet. Wenn Sie die Invarianten eines Handlers verletzen, wird ein TypeError ausgelst.

Handler und Fallen

Die folgende Tabelle fasst die verfgbaren Fallen zusammen, die fr Proxy-Objekte verfgbar sind. Siehe die Referenzseiten fr detaillierte Erklrungen und Beispiele.

Handler / Falle Abfangvorgnge
handler.getPrototypeOf() Object.getPrototypeOf()
Reflect.getPrototypeOf()
__proto__
Object.prototype.isPrototypeOf()
instanceof
handler.setPrototypeOf() Object.setPrototypeOf()
Reflect.setPrototypeOf()
handler.isExtensible() Object.isExtensible()
Reflect.isExtensible()
handler.preventExtensions() Object.preventExtensions()
Reflect.preventExtensions()
handler.getOwnPropertyDescriptor() Object.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor()
handler.defineProperty() Object.defineProperty()
Reflect.defineProperty()
handler.has()
Eigenschaftsabfrage
foo in proxy
Vererbte Eigenschaftsabfrage
foo in Object.create(proxy)
Reflect.has()
handler.get()
Eigenschaftszugriff
proxy[foo]
proxy.bar
Vererbter Eigenschaftszugriff
Object.create(proxy)[foo]
Reflect.get()
handler.set()
Eigenschaftszuweisung
proxy[foo] = bar
proxy.foo = bar
Vererbte Eigenschaftszuweisung
Object.create(proxy)[foo] = bar
Reflect.set()
handler.deleteProperty()
Eigenschafts-Lschung
delete proxy[foo]
delete proxy.foo
Reflect.deleteProperty()
handler.ownKeys() Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
handler.apply() proxy(..args)
Function.prototype.apply() und Function.prototype.call()
Reflect.apply()
handler.construct() new proxy(...args)
Reflect.construct()

Widerrufbarer Proxy

Die Methode Proxy.revocable() wird verwendet, um ein widerrufbares Proxy-Objekt zu erstellen. Das bedeutet, dass der Proxy ber die Funktion revoke widerrufen werden kann und der Proxy abgeschaltet wird.

Danach fhrt jede Operation am Proxy zu einem TypeError.

js
const revocable = Proxy.revocable(
  {},
  {
    get(target, name) {
      return `[[${name}]]`;
    },
  },
);
const proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"

revocable.revoke();

console.log(proxy.foo); // TypeError: Cannot perform 'get' on a proxy that has been revoked
proxy.foo = 1; // TypeError: Cannot perform 'set' on a proxy that has been revoked
delete proxy.foo; // TypeError: Cannot perform 'deleteProperty' on a proxy that has been revoked
console.log(typeof proxy); // "object", typeof doesn't trigger any trap

Reflexion

Reflect ist ein eingebautes Objekt, das Methoden fr abfangbare JavaScript-Operationen bietet. Die Methoden sind die gleichen wie die des Proxy-Handlers.

Reflect ist kein Funktionsobjekt.

Reflect hilft beim Weiterleiten von Standardoperationen vom Handler zum target.

Mit Reflect.has() zum Beispiel erhalten Sie den in-Operator als Funktion:

js
Reflect.has(Object, "assign"); // true

Eine bessere apply()-Funktion

Vor Reflect haben Sie typischerweise die Methode Function.prototype.apply() verwendet, um eine Funktion mit einem gegebenen this-Wert und Arguments, die als Array (oder ein Array-hnliches Objekt) bereitgestellt werden, aufzurufen.

js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);

Mit Reflect.apply wird dies weniger wortreich und einfacher zu verstehen:

js
Reflect.apply(Math.floor, undefined, [1.75]);
// 1

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4

Reflect.apply("".charAt, "ponies", [3]);
// "i"

berprfen, ob die Eigenschaftsdefinition erfolgreich war

Mit Object.defineProperty, das ein Objekt zurckgibt, wenn es erfolgreich war, oder ansonsten einen TypeError auslst, wrden Sie einen try...catch-Block verwenden, um einen beliebigen Fehler abzufangen, der beim Definieren einer Eigenschaft aufgetreten ist. Da Reflect.defineProperty() einen Boolean-Erfolgsstatus zurckgibt, knnen Sie hier einfach einen if...else-Block verwenden:

js
if (Reflect.defineProperty(target, property, attributes)) {
  // success
} else {
  // failure
}

Web Proxy Viewer  |  New URL  |  Original Page