JavaScript - Proxies: Ein Anfängerleitfaden

Hallo da draußen, angehende Programmierer! Heute werden wir eine aufregende Reise in die Welt der JavaScript Proxies antreten. Keine Sorge, wenn du noch nie von ihnen gehört hast – wir beginnen mit den ganz Basics und arbeiten uns hoch. Am Ende dieses Tutorials wirst du in der Kunst des Einsatzes von Proxies wie ein Profi versiert sein!

JavaScript - Proxies

Was ist ein Proxy in JavaScript?

Lassen wir mit einer einfachen Analogie beginnen. Stell dir vor, du bist ein berühmter Promi (warum nicht träumen, oder?). Du bist so berühmt, dass du jemanden brauchst, der deine Termine, Fanpost und andere tägliche Aktivitäten verwalten kann. Diese Person, die in deinem Namen handelt, wird im echten Leben als Proxy bezeichnet.

In JavaScript funktioniert ein Proxy auf ähnliche Weise. Es ist ein Objekt, das um ein anderes Objekt (lassen wir es das Zielobjekt nennen) gewickelt ist und grundlegende Operationen für dieses Objekt abfangen und neu definieren kann. Cool, oder?

Hier ist ein einfaches Beispiel, um uns zu started:

let target = {
name: "John Doe",
age: 30
};

let handler = {
get: function(target, property) {
console.log(`Zugriff auf die Eigenschaft ${property}`);
return target[property];
}
};

let proxy = new Proxy(target, handler);

console.log(proxy.name);

Wenn du diesen Code ausführst, wirst du sehen:

Zugriff auf die Eigenschaft name
John Doe

Lassen wir das auseinandernehmen:

  1. Wir haben ein target Objekt mit den Eigenschaften name und age.
  2. Wir erstellen ein handler Objekt mit einer get Falle (wir werden später mehr über Fallen sprechen).
  3. Wir erstellen einen proxy mit dem Proxy Konstruktor, indem wir unser target und handler übergeben.
  4. Wenn wir versuchen, proxy.name zuzugreifen, wird unsere get Falle ausgelöst, was eine Nachricht protokolliert, bevor der tatsächliche Wert zurückgegeben wird.

JavaScript Proxy Handler

Nun, da wir unsere Füße ins Wasser getaucht haben, tauchen wir tiefer ein in Proxy Handler. Ein Handler ist ein Objekt, das Fallen für unseren Proxy definiert. Fallen sind Methoden, die Eigenschaftssuche, Zuweisung, Enumeration, Funktionsaufrufe usw. bereitstellen.

Hier ist eine Tabelle einige gängiger Handler Fallen:

Falle Beschreibung
get Ermöglicht den Zugriff auf Eigenschaften
set Ermöglicht die Zuweisung von Eigenschaften
has Ermöglicht den Zugriff auf den in Operator
deleteProperty Ermöglicht den Zugriff auf den delete Operator
apply Ermöglicht den Zugriff auf Funktionsaufrufe
construct Ermöglicht den Zugriff auf den new Operator

Schauen wir uns ein umfassenderes Beispiel mit mehreren Fallen an:

let target = {
name: "Alice",
age: 25
};

let handler = {
get: function(target, property) {
console.log(`Zugriff auf die Eigenschaft ${property}`);
return target[property];
},
set: function(target, property, value) {
console.log(`Eigenschaft ${property} auf ${value} setzen`);
target[property] = value;
return true;
},
has: function(target, property) {
console.log(`Überprüfung, ob ${property} existiert`);
return property in target;
}
};

let proxy = new Proxy(target, handler);

console.log(proxy.name);  // Löst die get Falle aus
proxy.job = "Entwickler";  // Löst die set Falle aus
console.log("age" in proxy);  // Löst die has Falle aus

Wenn du diesen Code ausführst, wird die Ausgabe sein:

Zugriff auf die Eigenschaft name
Alice
Eigenschaft job auf Entwickler setzen
Überprüfung, ob age existiert
true

Ist das nicht toll? Unser Proxy fängt jetzt den Zugriff auf Eigenschaften, die Zuweisung und den in Operator ab!

Verwendung von Proxy-Objekten in JavaScript

Du könntest dich fragen, "Das ist cool und alles, aber wann würde ich das eigentlich verwenden?" Great question! Proxies haben mehrere praktische Anwendungen:

  1. Validierung: Du kannst Proxies verwenden, um Daten zu validieren, bevor sie auf ein Objekt gesetzt werden.
let user = {
name: "Bob",
age: 30
};

let validator = {
set: function(obj, prop, value) {
if (prop === "age") {
if (typeof value !== "number") {
throw new TypeError("Age muss eine Zahl sein");
}
if (value < 0 || value > 120) {
throw new RangeError("Age muss zwischen 0 und 120 liegen");
}
}
obj[prop] = value;
return true;
}
};

let proxiedUser = new Proxy(user, validator);

proxiedUser.age = 25;  // Das funktioniert
try {
proxiedUser.age = "dreißig";  // Das löst einen TypeError aus
} catch (e) {
console.log(e.message);
}
try {
proxiedUser.age = 150;  // Das löst einen RangeError aus
} catch (e) {
console.log(e.message);
}
  1. Protokollierung: Du kannst Proxies verwenden, um den Zugriff auf Objekteigenschaften zu protokollieren.
let target = {
name: "Charlie",
age: 35
};

let logger = {
get: function(target, property) {
console.log(`Eigenschaft ${property} wurde am ${new Date()} aufgerufen`);
return target[property];
}
};

let proxiedTarget = new Proxy(target, logger);

console.log(proxiedTarget.name);
console.log(proxiedTarget.age);
  1. Standardwerte: Du kannst Proxies verwenden, um Standardwerte für nicht existierende Eigenschaften bereitzustellen.
let handler = {
get: function(target, property) {
return property in target ? target[property] : "Eigenschaft nicht gefunden";
}
};

let proxy = new Proxy({}, handler);

proxy.name = "David";
console.log(proxy.name);  // Ausgabe: David
console.log(proxy.age);   // Ausgabe: Eigenschaft nicht gefunden

Liste der JavaScript Proxy Handler

Um unsere Reise in die Welt der JavaScript Proxies abzuschließen, werfen wir einen Blick auf eine umfassende Liste aller verfügbaren Handler Fallen:

Handler Falle Beschreibung
get Ermöglicht den Zugriff auf Eigenschaftswerte
set Ermöglicht das Setzen von Eigenschaftswerten
has Ermöglicht den Zugriff auf den in Operator
deleteProperty Ermöglicht den Zugriff auf den delete Operator
apply Ermöglicht den Zugriff auf Funktionsaufrufe
construct Ermöglicht den Zugriff auf den new Operator
getPrototypeOf Ermöglicht den Zugriff auf Object.getPrototypeOf
setPrototypeOf Ermöglicht den Zugriff auf Object.setPrototypeOf
isExtensible Ermöglicht den Zugriff auf Object.isExtensible
preventExtensions Ermöglicht den Zugriff auf Object.preventExtensions
getOwnPropertyDescriptor Ermöglicht den Zugriff auf Object.getOwnPropertyDescriptor
defineProperty Ermöglicht den Zugriff auf Object.defineProperty
ownKeys Ermöglicht den Zugriff auf Object.getOwnPropertyNames und Object.getOwnPropertySymbols

Und das war's! Wir haben die Basics der JavaScript Proxies behandelt, einige praktische Verwendungszwecke erkundet und sogar alle verfügbaren Handler Fallen angesehen. Denke daran, dass Proxies wie jedes mächtige Werkzeug vorsichtig eingesetzt werden sollten. Sie sind großartig für bestimmte Anwendungsfälle, aber sie bringen auch eine Leistungseinbuße mit sich.

Ich hoffe, dieses Tutorial hat dir geholfen, JavaScript Proxies zu enträtseln. Weiter üben, weiter coden, und bald wirst du wie ein Profi proxieren! Viel Spaß beim Coden!

Credits: Image by storyset