What is a Proxy?

JavaScript's method of intercepting and customizing object operations.

Konop.dev
Braden KonopFebruary 20, 2023

Intercepting and Customizing

In JavaScript, a proxy is an object that allows you to intercept and customize various operations performed on another object, called the target object. Proxies are useful in many contexts, including data validation, debugging, and security.

A proxy acts as a middleman between a client and a target object. When the client makes a request to the target object, the proxy intercepts the request and can modify it before passing it on to the target object. Similarly, when the target object returns a response to the client, the proxy can intercept and modify the response before passing it on to the client.

Proxies can intercept a variety of operations, such as property access, property assignment, function invocation, and object construction. For example, you can use a proxy to validate the values of properties before they are assigned to the target object, or to log all property accesses for debugging purposes.

Creating a Proxy

To create a proxy in JavaScript, you use the Proxy object, which takes two arguments: the target object and a handler object. The handler object defines the behavior of the proxy by specifying methods to intercept various operations.

Here is an example of creating a proxy:

emptyProxy.js
1const target = { name: 'James', age: 30 }; 2const handler = {}; 3 4const proxy = new Proxy(target, handler);

With an empty handler, the proxy will function just like the object. All attributes will be accessible to get or set.

1console.log(proxy.name); // 'James' 2console.log(proxy.age); // 30

Intercepting Getters

To intercept access to an attribute, like proxy.name in the above example, we can pass a get function to the handler like in this example:

nameRedactionProxy.js
1const target = { name: 'James', age: 30 }; 2const handler = { 3 get(target, prop, receiver) { 4 if (prop === 'name') { 5 return 'REDACTED'; 6 } 7 return Reflect.get(...arguments); 8 }, 9}; 10 11const proxy = new Proxy(target, handler);

Using this proxy, we are able to wrap any target object - say we have a series of objects representing people - and intercept any attempts to access their name, returning REDACTED instead.

1console.log(proxy.name); // 'REDACTED' 2console.log(proxy.age); // 30

If the attribute that is being accessed does not match what is listed in the conditional on line 4, the Reflect object is used to invoke the internal method of the object wrapped in the proxy. In other words, Reflect.get() uses the original functionality of the object.

Intercepting Setters

Not only can you intercept accesses to attributes, but you can intercept the object's values being changed. See the example below:

nameChangeValidation.js
1const target = { name: 'James', age: 30 }; 2const handler = { 3 set(obj, prop, value) { 4 if (prop) { 5 if (typeof value === "string") { 6 throw new TypeError("Name must be a string."); 7 } 8 if (0 > value.length || value.length > 15) { 9 throw new RangeError("Name must be between 0 and 15 characters."); 10 } 11 } 12 13 obj[prop] = value; 14 15 return true; 16 }, 17}; 18 19const proxy = new Proxy(target, handler);

In this example, every time we try to change the value of proxy.name, the proxy will check that:

  • The type of the value being assigned is a string

  • The length of the name is longer than 0 characters

Here we can see what happens when trying to set the value of proxy.name to various values:

1proxy.name = 123 2// Uncaught TypeError: Name must be a string. 3 4proxy.name = "ThisNameIsTooLongToUse" 5// Uncaught RangeError: Name must be between 0 and 15 characters. 6 7proxy.name = "Bruce" // 'Bruce'

Conclusion

In conclusion, proxies are a powerful tool in JavaScript that allow you to intercept and customize various operations performed on an object. With proxies, you can add validation, logging, and security checks to your code, making it more robust and reliable.

There is far more to know about proxies, so if you want a full technical rundown of everything you can do with them, refer to the MDN Web Docs.

© Copyright 2023 - Braden Konop. All rights reserved.