ES6 Proxies in der Praxis

Mit dem Erscheinen von ECMAScript 2015 kam eine Lawine von Funktionen; Einige von ihnen machen dich wütend, andere sind angenehme Überraschungen, wie das Treffen mit einem alten Freund nach langer Zeit.


Einige Funktionen beziehen sich auf die Metaprogrammierung. Was ist das Ich bin nicht sehr eloquent, also wenden wir uns an unseren Freund Wikipedia.


Metaprogrammierung ist eine Programmiertechnik, bei der Computerprogramme andere Programme als ihre Daten behandeln können. Dies bedeutet, dass ein Programm so gestaltet werden kann, dass es andere Programme liest, generiert, analysiert oder transformiert und sich sogar während der Ausführung selbst ändert. In einigen Fällen können Programmierer so die Anzahl der Codezeilen minimieren, um eine Lösung auszudrücken, was wiederum die Entwicklungszeit verkürzt. Darüber hinaus können Programme flexibler neue Situationen effizient handhaben, ohne sie neu kompilieren zu müssen.

Kurz gesagt, die Metaprogrammierung ermöglicht es einem Programm, andere oder sich selbst sowohl zur Kompilierungs- als auch zur Ausführungszeit zu manipulieren. Die Metaprogrammierung in JavaScript basiert auf zwei Funktionen: Proxy und Reflect API. In diesem Beitrag werden wir den ersten betrachten.


Proxy


Proxy ist eine neue API, mit der Objekte zur Laufzeit abgefangen, geändert und erweitert werden können. Mit dieser API können Sie:


  • Profil- und Debug-Protokolle,
  • Intercept-Aufrufe von Eigenschaften,
  • Validieren Sie "on the fly",
  • usw.

Proxy ist ein Konstruktor, der zwei Parameter akzeptiert: Quellobjekt und Objekt, das als Handler für das Quellobjekt fungiert. Letzteres enthält Methoden, die als Traps bekannt sind.



Eine Trap ist eine Methode, die das Verhalten eines Teils des Objekts ändert. Beispielsweise ruft der Trap die Aufrufe von Eigenschaften ab und setzt sie ab, um einen Wert zu erhalten bzw. festzulegen, und kann vor und während dieses Prozesses Logik platzieren.


Um die Nützlichkeit von Proxys besser zu verstehen, machen wir einige kleine Übungen.


Beispiel: Protokollierung / Profilerstellung


Stellen Sie sich vor, Sie sind 17 Jahre alt und werden bereits 18 Jahre alt. Und Sie möchten, dass Ihr Programm Ihnen beim Öffnen automatisch gratuliert. Hierfür können Sie Proxy verwenden.


et person = { name: "John Doe", age: 17 }; person = new Proxy(person, { set(target, property, value) { if (value === 18) { console.log("Congratulations! You are of legal age"); Reflect.set(target, property, value); return true; } } }); person.age = 18; Not only can we do logs, as I said at the beginning, we can do as far as the language limits us. Here we could make validations for the age, for example, if it exceeds 100 that throw us an error: if (value < 13 && value > 99) { throw new Error('The age should be between 13 and 99') } else { Reflect.set(target, property, value) } Example: secure access to properties let person = { name: "John Doe" }; const Undefined = new Proxy( {}, { get(target, name, receiver) { return Undefined; } } ); const Safeish = obj => { return new Proxy(obj, { get(target, property, receiver) { if (target.hasOwnProperty(property)) { const isObject = target[property] instanceof Object; return isObject ? Safeish(target[property]) : Reflect.get(target, property, receiver); } return Undefined; } }); }; person = Safeish(person); console.log(person.name); console.log(person.sister.name === Undefined); 

Beispiel: Abfrage-Array


Wir haben bereits ein Beispiel mit den am häufigsten verwendeten Fallen zum Abrufen und Setzen gesehen. Gehen wir zur Verstärkung etwas weiter und verwenden verschachtelte Proxys. In dieser Übung wird versucht, ein herkömmliches Array in ein abfragbares Array zu konvertieren, um Operatoren wie das klassische SQL groupBy zu verwenden.


Dazu benötigen wir zwei Eingabeparameter:


  • Sammlung: Array von Objekten, die wir erweitern werden.
  • groupKeys: Array von Zeichenfolgen, die die Eigenschaften darstellen, für die Sie eine Gruppe erstellen möchten (Name, Kategorie, Preis usw.)

 const data = [ { id: 1, category: 2, name: "Intel NUC Hades Canyon" }, { id: 2, category: 1, name: "Logitech K380" }, { id: 3, category: 1, name: "Genius ECO-8100" } ]; const groupable = (collection, groupKeys) => { // Check that the collection is an array if (!(collection instanceof Array)) { throw new TypeError("The input collection is not an Array"); } const data = JSON.parse(JSON.stringify(collection)); const clone = JSON.parse(JSON.stringify(collection)); Object.defineProperty(clone, "groupBy", { configurable: true, enumerable: false, writable: false, value: groupKeys.reduce((acc, cur) => { acc[cur] = null; return acc; }, {}) }); 

  return new Proxy(clone, { get(target, property, receiver) { if (property === "groupBy") { return new Proxy(target[property], { get(target, property, receiver) { // if the property to be grouped does not exist // log a warning and return [] if (!target.hasOwnProperty(property)) { return []; } // Otherwise, group by property return data.reduce(function(acc, cur) { (acc[cur[property]] = acc[cur[property]] || []).push(cur); return acc; }, {}); } }); } return Reflect.get(target, property, receiver); } }); }; const datasource = groupable(data, ["category"]); console.log(datasource.groupBy.category); 

Schlussfolgerungen


Der Proxy ist möglicherweise nicht die am häufigsten verwendete ES6-Funktion, aber zusammen mit der Reflect-API eine der wichtigsten und interessantesten. Seine Flexibilität ermöglicht die Übernahme in einer Vielzahl von Fällen und ist vor allem einfach zu implementieren.


Referenzen


https://es.wikipedia.org/wiki/Metaprogramaci%C3%B3n

Source: https://habr.com/ru/post/de448214/


All Articles