Javascript Proxy, hidden masterpiece?

I discovered my flow state while programming.
There are people that pick someone and improve them in a number of ways so that the selected one can assist them in their growth, much like an asset. I believe I am the one who has been chosen.
It hasn't been long since I first entered the software business as a rookie developer, and I've progressed from making internal team decisions, coaching juniors, presenting new standards to the team, and finding new ways to do remarkable things.
Currently, I'm working with JavaScript and associated technologies on a professional level
- Angular feels like home
- React
- NodeJs
- TypeScript
- I am a NoSQL guy, so "MongoDB" it is
- Spending some time with "NextJS" as well and its interesting
Intitially for hosting and deploying web apps I started with
- Heroku
- Vercel
CleverCloud
Then gradually shifted to AWS.
- EC2
- Also got know about SES, so started using it.
Recently I was introduced to Blockchain world, where I started working with
- Hyperlegder Fabrics
- Bash
- Docker
- Docker compose
- Docker swarm
As a web developer, you might have come across the term "proxy" in the context of web requests or server-side operations. However, in JavaScript, the term "proxy" takes on a whole new meaning. In this blog, we will explore JavaScript Proxy from a developer's perspective, covering its usage, syntax, and benefits.
What is a Proxy?
In JavaScript, a proxy is an object that wraps another object or function, intercepting all its operations and providing a way to customize or control them. In other words, it allows you to define custom behavior for fundamental operations on objects, such as property access, assignment, and deletion.
To create a proxy, you use the Proxy constructor, which takes two arguments: the object or function to be wrapped, and a handler object that defines the custom behavior for the wrapped object. The handler object contains a set of special functions called "traps," which are invoked when certain operations are performed on the proxy object.
Using Proxy
Let's look at a simple example of using a proxy in JavaScript:
const target = {
name: 'Ramesh',
age: 25
};
const handler = {
get: function(target, prop) {
console.log(`Getting property '${prop}'`);
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name);
//Output
// "Getting property 'name'"
// "Ramesh"
In this example, we create a target object with two properties: name and age. We then create a handler object with a get trap that logs a message to the console whenever a property of the proxy object is accessed, and returns the corresponding property value from the target object.
We then create a proxy object by calling the Proxy constructor with the target object and the handler object. Finally, we access the name property of the proxy object, which triggers the get trap and logs a message to the console, followed by the value of the name property from the target object.
Proxy Traps
The handler object can define several traps that intercept different operations on the proxy object. Here are some of the most commonly used traps:
get: Invoked when a property of the proxy object is accessed.set: Invoked when a property of the proxy object is assigned a new value.has: Invoked when theinoperator is used to check if a property exists on the proxy object.deleteProperty: Invoked when a property of the proxy object is deleted.apply: Invoked when the proxy object is called as a function.construct: Invoked when the proxy object is used as a constructor with thenewkeyword.
Each trap function takes two or more arguments, depending on the trap. The first argument is the target object, and the remaining arguments depend on the trap. For example, the get trap takes two arguments: the target object and the name of the property being accessed.
Benefits of Using Proxy
Using a proxy in JavaScript offers several benefits to developers, including:
Custom behavior: Proxies allow you to define custom behavior for fundamental operations on objects, giving you more control over how objects are accessed and manipulated.
Security: Proxies can be used to implement security features, such as preventing certain properties from being accessed or modified.
Debugging: Proxies can be used to log or intercept certain operations on objects, making it easier to debug code.
Compatibility: Proxies can be used to add new behavior to existing APIs, without breaking backward compatibility.
More Examples
Example 1: Preventing Property Access
const target = {
name: 'Ramesh',
age: 25
};
const handler = {
get: function(target, prop) {
if (prop === 'salary') {
throw new Error('Access denied');
}
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // "Ramesh"
console.log(proxy.salary); // throws "Access denied" error
In this example, we prevent access to the salary property of the proxy object by throwing an error in the get trap. This can be useful for implementing security features in your application.
Awesome! Isn't it?
Example 2: Interceptor for Function Calls
const target = {
add: function(a, b) {
return a + b;
}
};
const handler = {
apply: function(target, thisArg, args) {
console.log(`Calling function '${target.name}' with arguments: ${args.join(', ')}`);
return target.apply(thisArg, args);
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.add(2, 3)); // "Calling function 'add' with arguments: 2, 3" followed by 5
In this example, we log a message to the console whenever the add function of the proxy object is called, and also pass the call to the target object using the apply trap. This can be useful for logging function calls or intercepting and modifying their arguments.
Example 3: Adding New Properties
const target = {
name: 'Ramesh',
age: 25
};
const handler = {
get: function(target, prop) {
if (prop === 'greet') {
return function() {
console.log(`Hello, my name is ${target.name} and I am ${target.age} years old.`);
};
}
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // "Ramesh"
proxy.greet(); // "Hello, my name is Ramesh and I am 25 years old."
In this example, we add a new greet property to the proxy object, which is a function that logs a message to the console. This can be useful for adding new behavior to existing objects or APIs without modifying their original code.
Example 4: Checking Property Existence
const target = {
name: 'John',
age: 25
};
const handler = {
has: function(target, prop) {
if (prop === 'salary') {
return false;
}
return prop in target;
}
};
const proxy = new Proxy(target, handler);
console.log('name' in proxy); // true
console.log('salary' in proxy); // false
In this example, we prevent access to the salary property of the proxy object by returning `false
Conclusion
In conclusion, JavaScript Proxy is a powerful feature that allows developers to create custom behavior for objects and functions in their applications. By using traps, developers can intercept and modify property access, function calls, and more. With Proxy, you can add new features to existing APIs, implement security measures, and debug your code more easily.
While the concept of Proxy may be challenging for beginners, mastering this feature can greatly enhance your programming skills and open up new possibilities in your applications. With its versatility and flexibility, Proxy is one of the most exciting features of modern JavaScript.
So this is it for the moment, I am excited to have your feedback in the comments and discuss more about Proxy.
Till then, Happy Coding!


