📜 ⬆️ ⬇️

Practice using proxies in javascript

You may have heard that new objects appeared in ES6 JavaScript, the so-called proxies. Those who know what proxy objects are and know how to work with them, they can bring considerable benefits. Today we publish a translation of the material, which is aimed at explaining to all comers the peculiarities of working with JS proxy objects in many examples.

image

Also open our previous post in a new tab: JavaScript Proxy: both beautiful and useful.

What is a proxy?


A proxy, in a broad sense, is some kind of trusted entity acting on behalf of another entity. A proxy is a substitute for a real object, which has the right to act on behalf of and in the interests of this object. "Object" in this case can be almost anything. If we confine ourselves to considering proxies as applied to JavaScript, then we can say that these are special objects that allow you to intercept and modify actions performed on other objects. In particular, we are talking about calling functions, assignment operations, working with properties, creating new objects, and so on. This technology is used to block direct access to a target object or target function and to interact with an object or function through a proxy object.
')
Before we continue the conversation about proxies and move on to examples of working with them, consider three important terms that are directly related to them. Read more about it here .


Syntax


Here is the declaration of a simple proxy object to which the target object and handler are passed.

let proxy = new Proxy(target, handler); 

Check browser support for proxy objects


Let's start by checking the support of JavaScript proxy objects by the browser.

 let proxyTest = new Proxy({}, {}) if (proxyTest instanceof Object) { document.write("Proxy supported!"); } 

Standard behavior of objects


Here we will declare an object, and then we will try to access the non-existent property of this object.

 let obj = { c: "car", b: "bike" }; document.write(obj.b, " "); // -> "bike" document.write(obj.c, " "); // -> "car" document.write(obj.l); // -> "undefined" 

Use proxy for object


In the following example, we use a get interceptor handler. The handler will pass the target object and the requested key to the interceptor.

 let handler = {   get: function(target, name) {   return name in target ? target[name] : "Key does not exist"; } } let obj = { c: "car", b: "bike" }; let proxyObj = new Proxy(obj, handler); document.write(proxyObj.b, " "); // -> "bike" document.write(proxyObj.c, " "); // -> "car" document.write(proxyObj.l); // -> "Key does not exist" 

Get interceptor


The get interceptor is executed when attempting to access an object property using a proxy. The get method takes the target parameter (the object that needs to be worked through a proxy) and property (the property we are trying to access).

â–ŤSyntax


 var p = new Proxy(target, { get: function(target, property, receiver) { } }); 


â–ŤExample


In the following example, we will try to influence the value with the get interceptor before displaying it on the screen.

 let handler = { get: function(target, name) {   return name in target ? target[name]*10 : "Key does not exist"; } } let obj = { a: 1, b: 2 }; let proxyObj = new Proxy(obj, handler); document.write(proxyObj.a, " "); // -> 10 document.write(proxyObj.b, " "); // -> 20 document.write(proxyObj.c); // -> "Key does not exist" 

Interceptor set


The set interceptor is executed when trying to set an object property using a proxy. The set method accepts the target parameter (the object we are going to access), property (the property we are going to set), and value (the value of the property we are going to set).

â–ŤSyntax


 var p = new Proxy(target, { set: function(target, property, value, receiver) { } }); 


â–ŤExample


In the following example, we will add some properties to the object, assign values ​​to them, while doing so before declaring the proxy object (in the code it is called proxyObj ).

After analyzing this example, you can see that if, after declaring proxyObj try to set a new property of an object, the interceptor will be called and the value of the property changed by it will be saved in the object.

 let handler = { set: function(target, name, value) {   target[name] = value*10; } } let obj = { a: 1, b: 2 }; let proxyObj = new Proxy(obj, handler); proxyObj.c = 3; document.write(proxyObj.a, " "); // -> 1 document.write(proxyObj.b, " "); // -> 2 document.write(proxyObj.c); // -> 30 

Has interceptor


The has interceptor is called when the in operator is executed. The has method takes the target (target object) and property (property that you want to control access to using the proxy object).

â–ŤSyntax


 var p = new Proxy(target, { has: function(target, property) { } }); 


â–ŤExample


In the following example, we check if the substring ar is in the key. To begin with, we will check if the key exists, and, if so, we will check if it contains the substring of interest. If both conditions are met, we will return the logical value true , otherwise, we will return false .

 const handler = { has: function(target, key) {   if (key in target && key.includes("ar")) {     return true;   }   return false; } }; const user = { car: 'Bentley', bar: 4, hotel: "no", }; const proxy = new Proxy(user, handler); document.write('car' in proxy, " "); //  -> true document.write('car' in user, " "); //  -> true document.write('hotel' in proxy, " "); //  -> false document.write('hotel' in user, " "); //  -> true document.write('spacebar' in proxy, " "); //  -> false document.write('spacebar' in user); //  -> false 

Interceptor apply


The apply interceptor allows you to call a proxy with parameters. It allows you to override functions. The apply method takes the target parameters (the target object or the target function), thisArg ( this argument to use when calling), and argumentsList (a list of all the arguments in the form of an array).

â–ŤSyntax


 var p = new Proxy(target, { apply: function(target, thisArg, argumentsList) { } }); 


â–ŤExample


In the following example, we use a proxy to override a function that multiplies two numbers. A proxy changes the behavior of a function by adding 1 to the result of the multiplication.

 function multiply(a, b) { return a * b; } const handler = { apply: function(target, thisArg, argumentsList) {   return target(argumentsList[0], argumentsList[1]) + 1; } }; var proxy = new Proxy(multiply, handler); document.write(multiply(2, 5), " "); //  -> 10 document.write(proxy(2, 5)); //  -> 11 

Construct interceptor


The construct interceptor is executed when the new operator is called. In order for this interceptor to function normally, it is necessary that the target object, to work with which you plan to call it, could be created with a command like new Target() .

â–ŤSyntax


 var p = new Proxy(target, { construct: function(target, argumentsList, newTarget) { } }); 


â–ŤExample


In the following example, we will pass through a proxy a new value, to which a currency symbol has been added, to the constructor function.

 function formatCurrency(format) { this.format = format; } const handler = { construct: function(target, args) {   return new target("$" + args[0]); } }; const proxy = new Proxy(formatCurrency, handler); document.write(new proxy('100').format); //  -> $100 

Interceptor deleteProperty


The deleteProperty interceptor deleteProperty invoked when the delete method is invoked. It takes the target parameters (the target object or the target function), and property (the property whose removal command we want to process).

â–ŤSyntax


 var p = new Proxy(target, { deleteProperty: function(target, property) { } }); 

target: target.
property : the name of the property whose removal operation is to be intervened.

â–ŤExample


The following example demonstrates calling the function we need and performing certain actions when trying to delete an object property.

 const cars = { merc: 's320', buggati: 'veyron', }; const handler = { deleteProperty: function(target, prop) {   if (prop in target) {       document.write(`${prop} has been removed `); //  -> merc has been removed     delete target[prop];   } } }; document.write(cars.merc, " "); //  -> "s320" const proxy = new Proxy(cars, handler); delete proxy.merc; document.write(cars.merc, " "); //  -> undefined 

Proxy usage options


Here are some areas of practical use of proxies in JavaScript.


Results


In one of our previous materials about proxies in JS, which was published at the end of January of this year, we voted the following question: “Do you use proxies in your JS applications?”. Then it turned out that 13% of respondents answered “Yes”, 83% - “No”, and 4% chose the option “Other (in comments)”. The world of JavaScript is developing very fast. It is possible that the attitude of programmers to proxy objects has changed. Therefore, we offer everyone to help us find out and take part in today's survey.

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


All Articles