Let's Learn the Basics of JavaScript Proxies Used in Valtio

Proxies Are Heavily Used in Some of My Libraries

Hi,

I’m thinking about starting a series to explore how Proxies are used in Valtio. This first post will cover the basics. Later, I hope to dive into the actual implementation of Valtio, or maybe a simplified version.

What Are JavaScript Proxies?

Proxies are special objects that allow you to intercept and customize interactions with JavaScript objects. To create a Proxy, you simply pass a target object and a handler object to the Proxy constructor.

const p = new Proxy({}, {});

That’s it. The first argument is the target object, and the second is the handler object, which is empty in this case. If no handlers are provided, the Proxy behaves just like the original object.

There are many types of handlers, but let’s focus on two important ones: the get handler and the set handler.

The get Handler

The get handler intercepts read access to a property on the target object.

const p = new Proxy({ a: 1 }, {
  get(target, prop) {
    console.log('getting', prop);
    return target[prop]; // Emulates the default behavior (more or less)
  },
});

p.a; // Logs "getting a"

That should be easy to understand! Now, let’s look at the set handler.

The set Handler

The set handler intercepts write access when a property is assigned a new value.

const p = new Proxy({ b: 2 }, {
  set(target, prop, value) {
    console.log('setting', prop);
    target[prop] = value; // The default behavior (more or less)
    return true; // Indicates success
  },
});

p.b = 3; // Logs "setting b"

This is also straightforward, except for one important detail: the set handler must return a boolean value indicating whether the operation was successful. If it does not return true, JavaScript will throw a TypeError.

Wrapping Up

That’s pretty much it for the basics of Proxies. Our examples trap get and set, but still preserve the default behavior. Proxies also allow us to modify behavior, but I’m not a big fan of changing the expected behavior since it can be confusing for users. Instead, I believe Proxies should be used transparently, meaning they should keep the default behavior while adding useful functionality.

Most likely, Proxies are tools best suited for libraries, and we rarely need to use them directly in app development. Nevertheless, they are a powerful tool and can be used to solve certain problems.

Happy coding.

Reply

or to participate.