Proxy
Before we define how proxy works in Javascript, let's first define what a proxy is.
A proxy is an OOD (Object Oriented Design) pattern that is used to control access to an object. It is used to add extra functionality to an object without modifying the object itself.
In real world, proxy is used to control access to a building. For example, you can't enter a building without a security guard. The security guard is the proxy that controls access to the building so you get access to the building through the security guard.
Another world example is a bank. You can't access your bank account without a bank card. The bank card is the proxy that controls access to your bank account.
Now let's define it in Programming.
In programming, a proxy is used to control access to an object. For example, you can't access a private property of an object without a getter. The getter is the proxy that controls access to the private property of the object and so on.
Proxy in Javascript
Proxy is introduced to Javascript in ES6. It is used to control access to an object. It is used to add extra functionality to an object without modifying the object itself.
How it works
Let's see how proxy works in Javascript.
const user = {
name: "Hasan",
age: 20,
};
const userProxy = new Proxy(user, {
get(target, property) {
console.log("Getting property", property);
return target[property];
},
set(target, property, value) {
console.log("Setting property", property, "to", value);
target[property] = value;
},
});
userProxy.name = "Ahmed";
console.log(user.name); // Ahmed
As you can see, we used a proxy to access and modify the name
property of the user
object. The proxy is used to add extra functionality to the user
object without modifying the user
object itself.
Proxy structure
Now let's see the structure of the proxy.
The proxy is a class Proxy
that takes two arguments:
- The object that you want to control access to.
- An object that contains the handlers.
Let's write a simple and plain proxy.
const user = {};
const userProxy = new Proxy(user, {
// Handlers
});
Here we created a new instance of the proxy class and passed the object that we need to control access user
then in the second argument of the proxy constructor, it receives an object, that object contains handlers, now let's define what are the available handlers in the proxy.
Available handlers
There are 13 available handlers in the proxy, they are:
-
get
: It is used to get a property of an object, a getter in OOP. -
set
: It is used to set a property of an object, a setter in OOP. -
apply
: It is used to call a function. -
construct
: It is used to create a new instance of a class, corresponds to thenew
keyword andconstructor
method. -
has
: It is used to check if a property exists in an object, corresponds to thein
operator. -
deleteProperty
: It is used to delete a property from an object, corresponds to thedelete
operator. -
defineProperty
: It is used to define a new property in an object, corresponds to theObject.defineProperty
method. -
ownKeys
: It is used to get all the keys of an object, corresponds to theObject.keys
method. -
getOwnPropertyDescriptor
: It is used to get the property descriptor of a property in an object, corresponds to theObject.getOwnPropertyDescriptor
method. -
preventExtensions
: It is used to prevent adding new properties to an object, corresponds to theObject.preventExtensions
method. -
isExtensible
: It is used to check if an object is extensible, corresponds to theObject.isExtensible
method. -
getPrototypeOf
: It is used to get the prototype of an object, corresponds to theObject.getPrototypeOf
method. -
setPrototypeOf
: It is used to set the prototype of an object, corresponds to theObject.setPrototypeOf
method.
As you can see, each handler has a corresponding method in the normal object way.
Let's start with the most common used handlers, which you'll probably work with most of the time, they are get
, set
, has
, deleteProperty
get
The get
handler is used to get a property of an object, a getter in OOP.
const user = {
name: "Hasan",
age: 20,
};
const userProxy = new Proxy(user, {
get(target, property) {
console.log("Getting property", property);
return target[property];
},
});
console.log(userProxy.name); // Getting property name and returns Hasan
This handler takes two arguments:
- The target object, which is in our case the
user
object. - The property that we want to get, which is in our case the
name
property.
set
The set
handler is used to set a property of an object, a setter in OOP.
const user = {
name: "Hasan",
age: 20,
};
const userProxy = new Proxy(user, {
set(target, property, value) {
console.log("Setting property", property, "to", value);
target[property] = value;
},
});
userProxy.name = "Ahmed";
console.log(user.name); // Setting property name to Ahmed and returns Ahmed
This handler takes three arguments:
- The target object, which is in our case the
user
object. - The property that we want to set, which is in our case the
name
property. - The value that we want to set, which is in our case the
Ahmed
value.
has
This handler checks if the given property exists in our object.
const user = {
name: "Hasan",
age: 20,
};
const userProxy = new Proxy(user, {
has(target, property) {
console.log("Checking if property", property, "exists");
return property in target;
},
});
console.log("name" in userProxy); // Checking if property name exists and returns true
This handler takes two arguments:
- The target object, which is in our case the
user
object. - The property that we want to check if it exists, which is in our case the
name
property.
deleteProperty
Now let's delete a property from our object.
const user = {
name: "Hasan",
age: 20,
};
const userProxy = new Proxy(user, {
deleteProperty(target, property) {
console.log("Deleting property", property);
delete target[property];
},
});
delete userProxy.name;
console.log(user.name); // Deleting property name and returns undefined
This handler takes two arguments:
- The target object, which is in our case the
user
object. - The property that we want to delete, which is in our case the
name
property.
Use Cases for using Proxies in real world projects
Now let's see some use cases for using proxies in real world projects.
In our Ultimate Nodejs Course, we already have models to handle a single record of data, for example user data, we can use proxy to access the data without using the get
method.
class User {
constructor(private data: UserProps) {}
get(propName: string): string | number {
return this.data[propName];
}
}
const user = new User({ name: "Hasan", age: 20 });
const userProxy = new Proxy(user, {
get(target, property) {
return target.get(property);
},
});
console.log(userProxy.name); // Hasan
This is of course a very simple example, if you want to see the real implementation of it, keep up with the series it will be published within the next few days of this article.
🎨 Conclusion
In this article, we learned about the proxy, what is it, how to use it, and some use cases for using it in real world projects.
☕♨️ Buy me a Coffee ♨️☕
If you enjoy my articles and see it useful to you, you may buy me a coffee, it will help me to keep going and keep creating more content.
😍 Join our community
Join our community on Discord to get help and support (Node Js 2023 Channel).
📚 Bonus Content 📚
You may have a look at these articles, it will definitely boost your knowledge and productivity.
General Topics
- Event Driven Architecture: A Practical Guide in Javascript
- Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript
- After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
Packages & Libraries
- Collections: Your ultimate Javascript Arrays Manager
- Supportive Is: an elegant utility to check types of values in JavaScript
- Localization: An agnostic i18n package to manage localization in your project
React Js Packages
Courses (Articles)
Top comments (0)