DEV Community

Milek Agrawal
Milek Agrawal

Posted on • Updated on

Javascript Proxy: Introduction

JS is not truly an Object Oriented Programming language. Therefore fulfilling requirements such as Enforcing object property value validation during read and write and take action, defining a property as private, and detecting changes in values can be challenging. There are ways of solving the above-stated problems, such as by using a setter or getter to set default value or throw an error on validation checks. However, the more convenient way to handle these problems is by using the Proxy object.

Proxies are one of the hidden gems in Javascript that many developers do not know of. The Proxy object is a virtualising interface that allows us to control the behaviour of the object. It allows us to define custom behaviour for the basic operations of an object. Let's take an example to understand proxy in a better way.

Let us consider an item as shown below.

let item = {
    id: 1231,
    name: 'Stock',
    price: 136
}
Enter fullscreen mode Exit fullscreen mode

We want to sell this item but the condition is that the selling price should not be less than 100. At the same time, we want to put a check in place that throws the error if we try to read the value of a property that does not exist. Also, we want to define id as private property.

We can easily solve this problem by writing custom logic while performing get, set ,or property lookup. JS Proxy object exactly helps here. It allows us to add custom behaviour to the fundamental operations on a JS object.

To create a proxy object, we use the Proxy constructor and pass two parameters(target and handler) in it. Defining a Proxy object:

let proxy = new Proxy(target, handler);
Enter fullscreen mode Exit fullscreen mode

Target is the object which is virtualised using Proxy and adds custom behaviour to it. Here, item object is the target.

Handler is the object in which we define the custom behaviour. The handler object container the trap.

Traps are the methods that gives access to the target object’s property to the handler object. Traps are optional. If trap is not provided, target object’s default methods are used. There are different types of traps such as get, set, has, isExtensible, defineProperty, etc. You can use all of these traps in the handler to define the custom behaviour for target object.

let item = {
    id: 1231,
    name: 'Stock',
    price: 136
}

let handler = {
    // check while setting the value
    set: function(obj, prop, value) {
        if(prop === 'price') {
             if( !Number.isInteger(value)){
                throw new TypeError('Value passed is not a number');
            }
            if(value < 100){
                obj[prop]= 100;
                return true; 
            }
        }
        obj[prop]= value;
        return true; 
    },

    // check for no access to `id`
    // check for property which does not exist
    get: function(obj, prop) {
        if(prop == 'id'){
            throw new Error('Cannot access private property : id');
        }
        else {
            return prop in obj ?
            obj[prop] : new TypeError (prop + ' : property does not exist');
        }
    }
}

var itemProxy = new Proxy(item, handler);

Enter fullscreen mode Exit fullscreen mode

Let's understand the code. We created a proxy called itemProxy using the Proxy constructor and passed the item and handler to it.

Using the get trap in the handler, we are checking if the property exists in the object or not. Also, we have enforced id as private property and made it inaccessible.
Image description Image description Using the set trap in the handler, we are checking if the property passed is price, if the value being passed to assign is an integer and also, we are putting a modifier to assign the value 100 by default if the price is less than 100.

console.log(itemProxy.price); // 136
itemProxy.price = 45; 
console.log(itemProxy.price); // 100
Enter fullscreen mode Exit fullscreen mode

In a similar manner, we can define handlers to detect changes to the value of object properties which we will discuss some other time.

I hope this article helped all of us understand Proxies. To learn more, visit the MDN docs.

Love reading about Javascript, Web optimisations, Vue.js, React, and Frontend in general? Stay tuned for more.

Wanna connect? You can find me on LinkedIn, Twitter, GitHub.

Top comments (3)

Collapse
 
dhruvjoshi9 profile image
Dhruv Joshi

Thanks for adding it mate!

Collapse
 
milekag01 profile image
Milek Agrawal

Do checkout my other write-up as well
Tree shaking in Javascript

Collapse
 
sindouk profile image
Sindou Koné

Add to the discussion