Vorwort
In ES6 ist der Proxy -Konstruktor ein zugängliches globales Objekt. Mit dieser können Sie verschiedene Informationen über angeforderte Operationen zwischen dem Objekt und dem Verhalten verschiedener Betriebsobjekte sammeln und alles zurückgeben, was Sie tun möchten. Die Pfeilfunktionen, die Array -Dekonstruktion, die Ruheparameter und andere Merkmale in ES6 wurden weit verbreitet, sobald sie implementiert wurden, aber Funktionen wie Proxy werden von Entwicklern selten gesehen. Einerseits müssen die Entwickler auf die Vorteile dieser Merkmale aufgrund der Vorteile dieser Merkmale aufgrund der Vorteile dieser Merkmale ihre Nutzungsszenarien zutiefst verstehen. Persönlich mag ich den Stellvertreter von ES6 sehr, da wir den externen Zugriff auf Objekte auf prägnante und leicht verständliche Weise steuern können. Im Folgenden werde ich zuerst vorstellen, wie der Proxy verwendet wird, und dann spezifische Beispiele auflisten, um die Nutzungsszenarien von Proxy zu erläutern.
Proxy , siehe Name und Bedeutung, hat eine sehr ähnliche Funktion wie im Proxy -Modus im Entwurfsmodus, der häufig in drei Aspekten verwendet wird:
1. Überwachen Sie den externen Zugriff auf Objekte
2. Funktion oder Klassenkomplexität
3. Überprüfen Sie den Betrieb oder verwalten Sie die erforderlichen Ressourcen vor dem Betrieb
In einer Browserumgebung, die Proxy unterstützt, ist Proxy ein globales Objekt, das direkt verwendet werden kann. Proxy(target, handler) ist ein Konstruktor, target ist das, das das Objekt verfolgt wird, und handlder ist ein Objekt, das verschiedene Proxy -Operationen erklärt und schließlich ein Proxy -Objekt zurückgibt. Jedes Mal, wenn die Außenwelt über das Proxy -Objekt auf die Eigenschaften target zugreift, geht sie durch das handler -Objekt. Aus diesem Prozess ist das Proxy -Objekt sehr ähnlich wie Middleware (Middleware). Welche Operationen können also Proxy abfangen? Die häufigsten Vorgänge sind GET (lesen), Set (Modify) Objekteigenschaften usw. Klicken Sie hier, um eine vollständige Liste der interzeptablen Vorgänge zu erhalten. Darüber hinaus bietet das Proxy -Objekt auch eine revoke -Methode, mit der alle Proxy -Operationen jederzeit angemeldet werden können. Bevor wir den Proxy offiziell einführen, empfehlen wir Ihnen, ein gewisses Verständnis von Reflect zu haben, was auch ein neues globales Objekt ist, das ES6 hinzugefügt wurde.
Basic
const target = {name: 'Billy Bob', Alter: 15}; const Handler = {get (target, key, proxy) {const heute = new Date (); console.log (`Get Anfrage für $ {key} unter $ {Today}`); return reflect.get (Ziel, Schlüssel, Proxy); }}; const proxy = new Proxy (Ziel, Handler); Im obigen Code definieren wir zunächst ein target , das proxyiert werden soll, und deklarieren dann ein handler -Objekt, das alle Proxy -Operationen enthält. Als nächstes verwenden wir Proxy(target, handler) um den Proxy -Objekt proxy zu erstellen. Danach werden alle Zugriffe auf target mit proxy von handler verarbeitet.
1. Beenden Sie das Verifizierungsmodul
Beginnen wir mit einer einfachen Typüberprüfung, die zeigt, wie Sie Proxy verwenden, um die Genauigkeit von Datentypen sicherzustellen:
Sei numericDatastore = {count: 0, Menge: 1234, insgesamt: 14}; numericDatastore = new Proxy (numericDatastore, {set (Ziel, Schlüssel, Wert, Proxy) {if (TypeOF -Wert! }}); // Es wurde ein Fehler geworfen, weil "foo" kein numericDatastore ist.Wenn Sie einen Überprüfer direkt für alle Eigenschaften eines Objekts entwickeln möchten, können Sie die Codestruktur mit Verwendung von Proxy schnell aufblähen lassen.
Funktion createValidator (Ziel, Validator) {Neue Proxy zurückgeben (Ziel, {_validator: validator, set (Ziel, Schlüssel, Wert, Proxy) {if (target $ {key} bis $ {value}. }, Alter (val) {return typeof älter === 'nummer' && ay älter> 18; }} Klasse Person {Constructor (Name, Alter) {this.name = name; this.age = Alter; Return Creevalidator (dies, Personalidatoren); }} const Bill = neue Person ('Bill', 25); // Die folgenden Operationen melden eine Fehlerrechnung. Name = 0; bill.age = 'bill'; bill.age = 15; Durch die Trennung des Prüfers und der Hauptlogik können Sie den Inhalt personValidators -Verifizierer unendlich verlängern, ohne den entsprechenden Klassen oder Funktionen direkten Schaden zuzufügen. Um komplizierter zu sein, können wir auch Proxy verwenden, um die Typüberprüfung zu simulieren, um zu überprüfen, ob die Funktion Parameter mit korrekter Art und Menge empfängt:
Sei obj = {pickymethodon: function (obj, str, num) { / *... * /}, pickymethodtwo: function (num, obj) { / *... * /}}; const argTypes = {pickymethodon: ["Objekt", "String", "Number", Pickymethodtwo (", [", ",", "Objekt", "Objekt". {Get: Funktion (Ziel, Proxy) {var value = target [Schlüssel]; Funktion argChecker (Name, Args, Checkers) {for (var idx = 0; idx <args.Length; idx ++) {var arg = args [idx]; var type = Checkers [IDX]; if (! arg || typeof arg! == type) {console.warn (`Sie implementieren fälschlicherweise die Signatur von $ {name}. Überprüfen Sie Param $ {idx + 1}`); }}} obj.pickymethodone (); //> Sie implementieren fälschlicherweise die Signatur von Pickymethodon. Überprüfen Sie Param 1 //> Sie implementieren fälschlicherweise die Signatur von Pickymethodon. Überprüfen Sie Param 2 //> Sie implementieren fälschlicherweise die Signatur von Pickymethodon. Überprüfen Sie Param 3OBJ.Pickymethodtwo ("Wopdapodoo", {}); //> Sie implementieren fälschlicherweise die Signatur von Pickymethodon. Überprüfen Sie Param 3OBJ.Pickymethodtwo ("Wopdapodoo", {}); //> Sie implementieren fälschlicherweise die Signatur von Pickymethodon. Überprüfen Sie Param 3OBJ.Pickymethodtwo ("Wopdapodoo", {}); //> Sie implementieren fälschlicherweise die Signatur von Pickymethodtwo. Überprüfen Sie Param 1 // keine Warnungen loggedObj.pickymethodone ({}, "eine kleine String", 123); obj.pickymethodon (123, {});2. Private Attribute
In JavaScript oder anderen Sprachen ist es üblich, vor dem variablen Namen einen _ hinzuzufügen, um anzuzeigen, dass es sich um eine private Eigenschaft handelt (nicht wirklich privat), aber wir können nicht garantieren, dass niemand darauf zugreifen oder ändern wird. Im folgenden Code deklarieren wir einen privaten apiKey , um die Methodenaufrufe innerhalb des api -Objekts zu erleichtern, aber wir möchten nicht von außen auf api._apiKey zugreifen können:
var api = {_apikey: '123abc456def',/ * Mock -Methoden, die dies verwenden. api._apikey); // Get and mutate _apikeys wie gewünscht apikey = api._apikey; api._apikey = '987654321';Offensichtlich ist die Konvention ungehindert. Mit ES6 -Proxy können wir echte private Variablen implementieren. Das Folgende zeigt zwei verschiedene private Methoden für verschiedene Lesemethoden.
Die erste Methode besteht darin, SET/Get to Abce -Lese- und Schreibanforderungen zu verwenden und undefined:
let api = { _apiKey: '123abc456def', getUsers: function(){ }, getUser: function(userId){ }, setUser: function(userId, config){ }};const RESTRICTED = ['_apiKey'];api = new Proxy(api, { get(target, key, proxy) { if(RESTRICTED.indexOf(key) > -1) {Wurf -Fehler ($ {key} ist eingeschränkt. Bitte siehe API -Dokumentation für weitere Info.`); Reflect.get (Ziel, Schlüssel, Wert, Proxy);Die zweite Methode ist die Verwendung von Intercept im Betrieb:
var api = { _apiKey: '123abc456def', getUsers: function(){ }, getUser: function(userId){ }, setUser: function(userId, config){ }};const RESTRICTED = ['_apiKey'];api = new Proxy(api, { has(target, key) { return (RESTRICTED.indexOf(key) > -1) ? Falsch: Refled.has (Ziel, Schlüssel); Proxy verdeckt _apikey ... ")}}3. Zugriff auf Protokoll
Für Attribute oder Schnittstellen, die häufig aufrufen, langsam ausführen oder mehr Ressourcen in der Ausführungsumgebung aufnehmen, möchten Entwickler ihre Verwendung oder Leistung aufzeichnen. Zu diesem Zeitpunkt können sie Proxy verwenden, um als Middleware zu fungieren und die Protokollierungsfunktion einfach zu implementieren:
let api = { _apiKey: '123abc456def', getUsers: function() { /* ... */ }, getUser: function(userId) { /* ... */ }, setUser: function(userId, config) { /* ... */ }};function logMethodAsync(timestamp, method) { setTimeout(function() { console.log (`$ {timestamp} - Protokollierung $ {method} asynchron anfordern. }; api.getUsers ();4. Frühwarnung und Abfangen
Angenommen, Sie möchten nicht, dass andere Entwickler das noDelete -Attribut löschen und die Entwickler, oldMethod anrufen, verstehen, dass diese Methode aufgegeben wurde, oder den Entwicklern mitzuteilen, dass sie doNotChange -Attribut nicht ändern sollen. Dann können Sie Proxy verwenden, um es zu implementieren:
Lassen Sie DataStore = {nodelete: 1235, OldMethod: function () {/*...*/}, Donotchange: "Prouth and True"}; const nodelete = ['nodelete']; const nochange = ['donotchange']; const veraltet = ['OldMethod']; DataStore = New Proxy (DataStore, {set (Ziel, Schlüssel, Wert, Proxy) {if (nochange.includes (Schlüssel) {Wurf -Fehler (`error! $ {key} ist unveränderlich. Fehler ($! $ {Key} kann nicht gelöscht werden. Funktion (... args) {reflect.Apply (Ziel [Schlüssel], Ziel, Argumente);}: val; DataStore löschen.nodelete; DataStore.oldMethod ();5. Filterbetrieb
Einige Vorgänge werden Ressourcen sehr aufnehmen, z. B. das Übertragen großer Dateien. Wenn die Datei bereits in Stücken gesendet wird, müssen sie nicht entsprechend (nicht absolute) an die neue Anfrage erfolgen. Zu diesem Zeitpunkt können Sie Proxy verwenden, um die Funktion der Anfrage zu erkennen und herauszufiltern, welche nicht antworten müssen und welche nach den Funktionen antworten müssen. Der folgende Code zeigt kurz, wie man Funktionen filtert, nicht der vollständige Code. Ich glaube, jeder wird die wunderbaren Dinge verstehen:
Sei obj = {getGiantFile: function (fileId) {/*...*/}}; obj = new Proxy (obj, {get (Ziel, Schlüssel, Proxy) {return function (... args) {const id = args [0]; let isenroute = checkEnroute (id); (IsenRoute || Isdownloading) {return false;6. Interrupt Agent
Proxy unterstützt jederzeit Unroxy für target , wodurch häufig der Zugriff auf Daten oder Schnittstellen vollständig eingeschlossen wird. Im folgenden Beispiel haben wir die Proxy.revocable Methode verwendet, um ein Proxy -Objekt zu erstellen, das revocable Proxies:
Sei sensisitedata = {userername: 'devBryce'}; const {sensitivedata, revokeAccess} = proxy.Revocable (sensibiledata, Handler); HandleSusworedHack (); // typeerror: recokedConsole.log (sensibiledata.username);Dekorateur
Der in ES7 implementierte Dekorateur entspricht dem Dekorationsmodus im Designmodus. Wenn Sie einfach die Nutzungsszenarien von Proxy und Dekorateur unterscheiden, kann dies als: Die Kernfunktion von Proxy besteht darin, den Zugang der Außenwelt zum Agenten zu kontrollieren, und die Kernfunktion des Dekors ist es, die Funktionen des Dekorationsmittels zu verbessern. Solange sie einen guten Unterschied in ihren Kernnutzungsszenarien machen, Funktionen wie Zugriffsprotokolle, obwohl dieser Artikel die Proxy -Implementierung verwendet, können sie auch mit dem Dekorator implementiert werden. Entwickler können basierend auf Projektbedürfnissen, Teamspezifikationen und ihren eigenen Vorlieben frei wählen.
Zusammenfassen
Der Stellvertreter von ES6 ist immer noch sehr praktisch. Die scheinbar einfachen Funktionen sind von großem Nutzen. Ich hoffe, es wird für alle hilfreich sein, ES6 zu lernen.