Use cases for Proxy in JavaScript
A proxy in JavaScript is an object that acts as an interface to another object, allowing you to intercept and customize operations performed on that object. This can be useful for a variety of purposes, such as logging, validation, access control and caching.
In the rest of the article I will list 3 of the use cases.
Validation using Proxy
In this example, we'll create a proxy for an object that validates the data being passed to it:
// This is the interface we want to restrict the data to
const personModel = {
fullName: '',
age: 0,
};
// This is the validator which will be used by the Proxy
const modelValidator = {
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new TypeError('Age must be a number');
}
if (prop === 'fullName' && typeof value !== 'string') {
throw new TypeError('Full name must be a string');
}
if (!Object.keys(target).includes(prop)) {
throw new TypeError('You cannot set anything else other than age and full name');
}
return Reflect.set(target, prop, value);
},
};
Now if we attempt to instantiate a new object and we try to set a property which does not respect the model, an error will be thrown because we are not allowed to set gender to the useDaniel object. Noticed that we have two more validation cases for value type in regards to age and fullName.
const userDaniel = new Proxy(personModel, modelValidator);
userDaniel.fullName = 'Daniel Smith';
userDaniel.age = 55;
userDaniel.gender = "male";
// Output: TypeError: You cannot set anything else other than age and full name
Access control with Proxy
In this example, we'll create a proxy for an object that restricts access to certain properties:
const secretData = {
secret: 'This is super secret',
public: 'This is public stuff',
misc: 'Other stuff'
};
const handler = {
get(target, prop, receiver) {
if (prop === 'secret') {
throw new Error('Access denied');
}
return Reflect.get(target, prop, receiver);
},
};
const data = new Proxy(secretData, handler);
console.log(data.public);
// Output: This is public stuff
console.log(data.secret);
// Output: Error: Access denied
As you can see, the proxy restricts access to the "secret" property, throwing an error if an attempt is made to access it.
Caching with Proxy
In this example, we'll create a proxy for a function that caches its results:
function expensiveOperation(n) {
console.log(`Performing expensive operation for ${n}`);
return n * n;
}
const cache = new Map();
const handler = {
apply(target, thisArg, args) {
const key = args[0];
if (cache.has(key)) {
console.log(`Returning cached result for ${key}`);
return cache.get(key);
}
const result = Reflect.apply(target, thisArg, args);
cache.set(key, result);
return result;
},
};
const calculate = new Proxy(expensiveOperation, handler);
console.log(calculate(50000));
// Output: Performing expensive operation for 50000, 2500000000
console.log(calculate(50000));
// Output: Performing expensive operation for 50000, 2500000000
In this example, we've created a proxy for a function that performs an expensive operation. We've added a caching step to the apply handler, which checks if the result of the operation has already been cached. If it has, the proxy returns the cached result instead of performing the operation again.
As we've seen, proxies in JavaScript can be used for a variety of purposes, validation, access control caching and more. By intercepting and customizing operations performed on objects, proxies give developers a lot of flexibility in how they use and manipulate data in their applications. By mastering proxies, developers can create more powerful and efficient code.
Thank you for following so far.