Proxy Pattern
Intercept and control interactions to target objects
Overview
The Proxy Pattern uses a Proxy intercept and control interactions to target objects.
Let's say that we have a person object. We can access properties with either dot or bracket notation,
and modify property values in a similar fashion.
With the Proxy pattern, we don't want to interact with this object directly. Instead, a Proxy object intercepts the request, and (optionally) forwards this to the target object - the person object in this case.
Implementation
In JavaScript, we can easily create a new proxy by using the built-in Proxy object.

The Proxy object receives two arguments:
- The target object
- A handler object, which we can use to add functionality to the proxy. This object comes with some built-in functions that we can use, such as
getandset.
The get method on the handler object gets invoked when we want to access a property, and the set method gets invoked when we want to modify a property.
const person = {
name: "John Doe",
age: 42,
email: "john@doe.com",
country: "Canada",
};
const personProxy = new Proxy(person, {
get: (target, prop) => {
console.log(`The value of ${prop} is ${target[prop]}`);
return target[prop];
},
set: (target, prop, value) => {
console.log(`Changed ${prop} from ${target[prop]} to ${value}`);
target[prop] = value;
return true;
},
});Reflect
The built-in Reflect object makes it easier to manipulate the target object.
Instead of accessing properties through obj[prop] or setting properties through obj[prop] = value, we can access or modify properties on the target object through Reflect.get() and Reflect.set(). The methods receive the same arguments as the methods on the handler object.
Tradeoffs
Control: Proxies make it easy to add functionality when interacting with a certain object, such as validation, logging, formatting, notifications, debugging.
Long handler execution: Executing handlers on every object interaction could lead to performance issues.
Exercise
Challenge
Add the following validation to the user object:
- The
usernameproperty has to be astringthat only contains of letters, and is at least 3 characters long - The
emailproperty has to be a valid email address. - The
ageproperty has to be a number, and has to be at least18 - When a property is retrieved, change the output to
${new Date()} | The value of ${property}} is ${target[property]}. For example if we getuser.name, it needs to log2022-05-31T15:29:15.303Z | The value of name is John