Proxy Design Pattern In JavaScript

In JavaScript, a proxy is an object that allows you to intercept and customize operations on another object (known as the target). Proxies provide a way to define custom behavior for fundamental operations like property access, function invocation, and more. They are part of the ECMAScript 6 (ES6) specification and are widely used for various purposes, such as logging, validation, and security.

To create a proxy object, you can use the Proxy constructor, which takes two arguments:

  1. The target object: This is the object that you want to proxy and intercept operations on.

  2. The handler object: This is an object containing methods (known as traps) that define the custom behavior for different operations.

What Is Trap?

In the context of JavaScript proxies, a "trap" refers to a special method or function that you define in the handler object when creating a proxy. These trap methods define custom behavior for specific operations performed on the proxy target object. Each trap corresponds to a particular operation, allowing you to intercept and customize that operation. The most commonly used traps include:

  • get(target, prop, receiver): This trap is called when you access a property of the proxy using the dot notation or square bracket notation.

  • set(target, prop, value, receiver): This trap is called when you assign a value to a property of the proxy using the assignment operator (=).

  • has(target, prop): This trap is called when you use the in operator to check if a property exists in the proxy.

  • deleteProperty(target, prop): This trap is called when you use the delete operator to delete a property from the proxy.

target - proxy target object

prop - property being operated

value - new value being assigned

receiver - the proxy object itself.

Let's create a basic example for creating a javascript proxy:-

// Target Object
const person = {
    name: "Akash",
    age: 20
}

// Create handler with traps
const handler = {
    get(target, prop, receiver){
        return Reflect.get(target, prop);
    },

    set(target, prop, value){
        if(prop === "age"){
            if(typeof value !== "number"){
                console.log(`${prop}: Invalid datatype`);
            }
            else{
            Reflect.set(target, prop, value);
            }
        }

    }
}

// Create proxy object
const personProxy = new Proxy(person, handler);

console.log(person); // {name: "Akash", age: 20}
personProxy.age = "21"; // age: Invalid datatype
console.log(person); // {name: "Akash", age: 20}

In the above example we are validating age property, here we restricting user to enter wrong value (other than number datatype).

Just like the 'age' property, you can also add validation to the 'name' property or perform any other operation before assigning a value to a property or accessing a property.

What is Reflect Object?

The Reflect object is a built-in object that provides a set of static methods that correspond to various fundamental operations on objects. These methods are often used in conjunction with JavaScript proxies to implement default behavior for certain traps or to forward operations to the target object. The methods provided by the Reflect objects are similar to the internal methods used by JavaScript's syntax.

Thanks For Reading❤