Home

3 minute read

Introduction to Javascript Proxy

Tony Lea

Introduction to Javascript Proxy

What is a Javascript Proxy? Glad you asked because in this quick tutorial I'm going to teach you what they are and how to use them.

But first, a quick definition. A Javascript Proxy is simply an object that listens for changes. Using a proxy you can define custom rules for any object anytime a value is saved or retrieved. It will make much more sense if you take a look at the examples below 👇.

A Simple Person Object

We are going to use a simple Person javascript object to show you how to use a proxy. Here is an example of our Person object:

let Person = {
    firstName: "mike",
    lastName: "jones",
    age: 25
}

Nothing too fancy here. It's a simple object containing a person with the name mike jones who is 25 years old. Using this object we can change the first name with the following code:

Person.firstName = "robert";
console.log(Person);

// This would output the following object
{
    firstName: "robert",
    lastName: "jones",
    age: 25
}

Pretty straight forward, right? But, what if we wanted to monitor this object and modify functionality whenever we set or get data from the object? That's where a Javascript Proxy comes in handy.

A Proxy Object

Assuming that we have the same Person object from above we can create a Proxy from that object, like so:

let PersonProxy = new Proxy(Person, {});

We could now use this Proxy object as if it were the original object.

console.log(PersonProxy.lastName); // jones

That's the simplest form of a Proxy; however, if we want to leverage the Javascript Proxy and take advantage of all it's awesome powers, we can use a few Handler Methods, such as get() and set(). Here is an example of a Proxy using the get() method:

let PersonProxy = new Proxy(Person, {
    get(target, property){
        if(property == 'firstName' || property == 'lastName'){
            return target[property].charAt(0).toUpperCase() + target[property].slice(1);
        }
        return target[property];
    }
});

Inside of the get() method 👆 above we are checking to see if the property is either the firstName or the lastName and if so it will capitalize the first character.

console.log(PersonProxy.lastName) // Jones

Pretty cool, right? Using a Proxy will allow us to add some more functionality whenever we want to retrieve data from that specific object. On the other hand we can also add custom functionality whenever we set() data for our object:

let PersonProxy = new Proxy(Person, {
    set(target, property, value) {
        target[property] = value.charAt(0).toUpperCase() + value.slice(1);
    }
});

If we use the Proxy from this example we can set the value: PersonProxy.firstName = "robert"; and it will run our custom functionality. Now the value of our Person object would be the following:

{
    firstName: "Robert",
    lastName: "jones",
    age: 25
}

Using a Javascript Proxy will allow us to add dynamic functionality when setting and getting data from an object. There is so much more you can do with a Proxy, but this was just a simple example to get your feet wet.

Two-way Data-binding with a Proxy

I'm sure you've seen 2-way data-binding in some of you favorite javascript frameworks like Vue, React, and Alpine. In most cases these technologies are using a Proxy to create this binding. Here is a quick example, here is some simple HTML:

<input type="text" id="firstName" name="firstName" value="">
<p id="firstNameDisplay"></p>

We have a simple text input and a paragraph. Next, we can create a simple Proxy that will get updated anytime we detect a keyup event on the input.

let Person = { firstName: "" }

let PersonProxy = new Proxy(Person, {
    set(target, property, value) {
        target[property] = value;
        if(property == 'firstName'){
            document.getElementById('firstNameDisplay').innerText = Person.firstName;
        }
    }
});

document.getElementById('firstName').addEventListener('keyup', function(e){
   PersonProxy.firstName = this.value;
});

Here is a quick example of the code above. Try typing in a value in the text input and you'll see that the Person object automatically gets updated via the Proxy 👏

Note: we could have made this 2-way data-binding functionality more modular and re-usable; however, for the sake of simplicity we just hardcoded some ID's to the elements.

Conclusion

There's so much cool stuff you can do with a Javascript Proxy including computed properties, overriding deletion of data, and so much more.

Here's an example of a computed property using our Person object from above:

let PersonProxy = new Proxy(Person, {
    get(target, property) {
        if (property === 'fullName') {
            return target.firstName + ' ' + target.lastName;
        }

        return target[property];
    }
});

console.log(PersonProxy.fullName); // mike jones

You can see that above we have created a computed property called fullName, which will return the first and last name of the person.

Be sure to play around with the Javascript Proxy and learn about all the different Handler methods you can use to create some really cool functionality. Hope this helps you grasp the basic concepts of the Javascript Proxy 🤙

Cheers 🍻