Introduction

In JavaScript, we have the ability to create proxy objects which can intercept and modify the behavior of an existing object. This powerful feature is made possible through the use of the Proxy native object, introduced in ES2015.

Creating a Proxy Object

To create a proxy object, we start with an existing object that we want to enhance. Let’s consider a simple example where we have a car object:

const car = {
 color: 'blue'
}

Intercepting Property Access

One common use case for proxies is to intercept property access and modify the behavior when a property does not exist. To achieve this, we define a handler object with a get() method. The get() method takes in the target object and the property name as parameters:

const handler = {
 get(target, property) {
 return target[property] ?? 'Not found'
 }
}

Next, we initialize our proxy object by calling new Proxy() and passing in the original object (car) and our handler:

const proxyObject = new Proxy(car, handler)

Now, when we access a property on proxyObject, it will behave just like accessing the property directly on car:

proxyObject.color //'blue'

However, if we try to access a property that doesn’t exist on car, like test, we will receive the 'Not found' string instead of undefined:

proxyObject.test //'Not found'

Additional Proxy Methods

Apart from the get() method, there are several other methods (also called traps) that we can use in a proxy handler to control different aspects of object behavior. These include:

  • apply: called when apply() is used on the object
  • construct: called when the object constructor is accessed
  • deleteProperty: executed when a property deletion is attempted
  • defineProperty: called when a new property is defined on the object
  • set: executed when a property is set

There are also other traps such as enumerate, getOwnPropertyDescriptor, getPrototypeOf, has, isExtensible, ownKeys, preventExtensions, and setPrototypeOf, each corresponding to a specific functionality. Detailed information about each trap can be found on the MDN documentation.

Example: Preventing Property Deletion

Let’s consider an example using the deleteProperty trap. Suppose we want to prevent the deletion of properties from an object:

const car = {
 color: 'blue'
}

const handler = {
 deleteProperty(target, property) {
 return false
 }
}

const proxyObject = new Proxy(car, handler)

If we attempt to delete the color property using delete proxyObject.color, it will result in a TypeError:

TypeError: 'deleteProperty' on proxy: trap returned falsish for property 'color'

By using a proxy, we can encapsulate our logic and prevent property deletion if desired.

Conclusion

JavaScript Proxy objects provide a powerful way to intercept and modify the behavior of existing objects. By utilizing proxy methods, we can implement custom rules and controls to enhance the functionality of our objects. Proxies enhance the flexibility and extensibility of our code, allowing us to create more robust and secure applications.

Tags: JavaScript, Proxy Object, Object Behavior, Proxies