DEV Community

Cover image for Discovering the Power of JavaScript Proxy After All This Time
Marc Lipovsky
Marc Lipovsky

Posted on

Discovering the Power of JavaScript Proxy After All This Time

As an engineer who has spent most of my time in JavaScript for over 25 years, I thought I had seen it all. I've conquered callbacks, made friends with promises, and even tamed the mighty async-await beast. Yet, one day, I stumbled upon a hidden gem I had never used before: the JavaScript Proxy.

It took me a quarter of a century to discover this versatile and powerful feature that has been sitting there, waiting to be unveiled. So, if you're like me and have overlooked JavaScript Proxy all these years, allow me to show you some intriguing use cases that might just change the way you write JavaScript.

1. Validation

Have you ever felt the need to put a leash on your object's properties to ensure data integrity? With Proxies, you can add validation checks when setting property values. It's like having a personal bodyguard for your data!

const validationHandler = {
  set: function (target, property, value) {
    if (property === 'age' && (typeof value !== 'number' || value <= 0)) {
      throw new TypeError('Age must be a positive number');
    }
    target[property] = value;
    return true;
  },
};

const person = new Proxy({}, validationHandler);
person.age = 25; // OK
person.age = -5; // Throws TypeError
Enter fullscreen mode Exit fullscreen mode

2. Logging and profiling

Debugging can often feel like searching for a needle in a haystack. Why not let Proxies lend you a hand by logging or profiling operations on your objects? It's like having your very own private investigator!

const loggingHandler = {
  get: function (target, property) {
    console.log(`Getting ${property}`);
    return target[property];
  },
  set: function (target, property, value) {
    console.log(`Setting ${property} to ${value}`);
    target[property] = value;
    return true;
  },
};

const loggedObject = new Proxy({}, loggingHandler);
loggedObject.foo = 42; // Logs: "Setting foo to 42"
console.log(loggedObject.foo); // Logs: "Getting foo" and 42
Enter fullscreen mode Exit fullscreen mode

3. Access control

Protect your object's properties like Fort Knox by enforcing access control. With Proxies, you can make certain properties read-only or restrict access based on specific conditions. It's like having an impenetrable security system!

const readOnlyHandler = {
  set: function (target, property, value) {
    if (property === 'readOnly') {
      throw new Error('Cannot modify read-only property');
    }
    target[property] = value;
    return true;
  },
};

const protectedObject = new Proxy({ readOnly: true }, readOnlyHandler);
protectedObject.newProperty = 'some value'; // OK
protectedObject.readOnly = false; // Throws Error
Enter fullscreen mode Exit fullscreen mode

4. Lazy loading

Why do all the hard work upfront when you can take it easy? Proxies enable you to implement lazy loading of object properties, only computing or fetching values when they're actually accessed. It's like having a personal assistant to manage your workload!

const lazyLoadHandler = {
  get: function (target, property) {
    if (!target[property]) {
      target[property] = expensiveComputation();
    }
    return target[property];
  },
};

const lazyLoadedObject = new Proxy({}, lazyLoadHandler);
const result = lazyLoadedObject.expensiveProperty; // Calls expensiveComputation() on first access
Enter fullscreen mode Exit fullscreen mode

5. Computed properties

Transform your objects into clever mathematicians by creating computed properties. Proxies let you compute values based on other properties, making your objects smarter and more flexible. It's like having a built-in calculator!

const computedHandler = {
  get: function (target, property) {
    if (property === 'fullName') {
      return `${target.firstName} ${target.lastName}`;
    }
    return target[property];
  },
};

const user = new Proxy({ firstName: 'John', lastName: 'Doe' }, computedHandler);
console.log(user.fullName); // Logs: "John Doe"
Enter fullscreen mode Exit fullscreen mode

So there you have it, folks! After 25 years of being a JavaScript aficionado, I have finally come to appreciate the power and versatility of JavaScript Proxy (MDN). It's never too late to learn something new and add a shiny tool to your developer toolbox!

Now, it's your turn! How have you used JavaScript Proxy in your projects? Share your creative and innovative use cases in the comments section below. Let's embark on this Proxy journey together and see where it takes us!

Top comments (18)

Collapse
 
zyabxwcd profile image
Akash • Edited

I read about Proxy a while back and then forgot about it. You covered all and more use cases I read back then. Its indeed powerful but then comes this thing, its so widely unknown, that if I go ahead and implement it in my project where there are other developers working with me, they will find it complicated and secretly hate me for it. I know it doesn't sound very good but that's just it. I often see this where many developers want to resort to things that are widely known and utterly simple to understand. To be able to understand why they are getting some errors and how they need to write code around it, accounting for the Proxy in place, they will need to understand and read about Proxy, which they will find as an overhead for sure. (At least most of the devs I have encountered falls in that category till now, sadly) Even some of the seniors I have seen, say that use things that are easy to understand for others and don't complicate things. They would want me to build something using the classic normal functions or functional programming way or rather build a middleware of some sorts that the devs can invoke (each time they want to) to do things done in the Proxy hooks.
People have a weird mindset sometimes where they question that how will a normal dev know that a Proxy is in place and the purpose for it, had it been a normal function/middleware, they would have understood it right away. The special features modern languages offer like Proxy, Decorators etc I think people use or want to use in special situations only where they are absolutely needed, otherwise even though they might ease the task at hand or fit in but still people tend to avoid them.
On second thought, I wonder if the things I mentioned, is the reason that Proxy is not so famous or widely used in general development in the first place as I see. Would love to hear the communities thoughts on what I wrote.

Collapse
 
marclipovsky profile image
Marc Lipovsky

You bring up valid concerns about using lesser-known features like Proxy in shared projects. It's important to find a balance between powerful language features and maintainable code for the whole team. And you're absolutely right that some devs might see advanced features like Proxy, Decorators, or custom classes as overcomplicating things.

But because these are native APIs, they do allow for efficient, clean, and robust code. Weighing the pros and cons of using these features against the benefits of keeping the code as simple and clear as possible is definitely a good practice on it's own.

One way to ease concerns is to provide documentation, comments, and internal presentations to help your teammates get familiar with these concepts (sharing articles like this one). Consistency in using these features also helps devs appreciate their advantages.

Collapse
 
robtweed profile image
robtweed

Two of my examples that make pretty advanced use of proxies: github.com/robtweed/DPP
github.com/robtweed/glsdb

Both are about creating JS objects that happen to be persistent, DPP being browser-based, and glsdb being for the Node.js back-end

Another use of proxies can be found in my Golgi WebComponent framework:
github.com/robtweed/golgi

where a proxy is used for data binding/state

Proxies are seriously powerful, but do take some time to “get”, and can be a bit mind-bending, but hopefully my examples give you some ideas for further use cases

Collapse
 
marclipovsky profile image
Marc Lipovsky

Umm yes, these are much more advanced and powerful uses of the Proxy API.Great work on them!

I'm finding that the more examples (like yours) I see of the Proxy API, the more I am understanding how it can be used.

Thanks for sharing!

Collapse
 
keltroth profile image
Django Janny

If you're looking for more advanced uses of proxy, Vue is a great example, here note some words from its creator : increment.com/frontend/making-vue-3/

Thread Thread
 
marclipovsky profile image
Marc Lipovsky

Love Increment! Thanks for sharing this I keep finding more advanced uses and might do a follow up.

Collapse
 
leonsegal profile image
Leon Segal

I really enjoyed this post, it was clear and straightforward.

Collapse
 
aren55555 profile image
Aren Patel

I've found that the JS/TS Proxy pattern is a great way to substitute or wrap an implementation; especially when working within TypeScript (it accepts a generic arg). We've used it to transparently (to the caller) replace our logger implementation from Winston to Pino in our Node.js backend. It's worked well for us in these "upgrade" (aka replacement) contexts.

I do find the Proxy code and MDN documentation hard to initially understand. However, once you've got a good understanding and have a few reps under your belt it becomes a really powerful tool in a JS/TS developers toolkit.

I'd also suggest an older programming book Design Patterns, Elements of Reusable Object-Oriented Software which has an entire section on Proxies. The book highlights some of the kinds of problems that are solved well by the Proxy pattern. It also does a good job of highlighting other software abstraction patterns; such as Observers, Facades, etc. Even though this book was written in the early 90s, the patterns described are language-agnostic and still applicable today. I frequently find myself referring back to this "manual" to this day.

Collapse
 
schemetastic profile image
Rodrigo Isaias Calix

Hello!

I agree! MDN Docs is super useful, if I were a sort of batman-developer (I might be or may not...) that definitively would go in my utility belt, honestly I'm not much of a book reader but sometimes in rare occasions...hahaha... nevertheless those books seem very interesting.

If I can show you, a place where I have learned a lot of Proxies and you might found it useful too is at Go Make Things, I'm not trying to be spammy here, but this is sometimes my go-to place to learn some good quality JS, check out these articles relate to proxies:

gomakethings.com/search/?s=proxy

Hope it helps!

Collapse
 
dannyengelman profile image
Danny Engelman • Edited

You might want to change that 25 years to 10

It was available earlier in Flash ActionScript.. which was ECMAScript based

Good read, if you like JavaScript history: The real story behind ES4

Collapse
 
marclipovsky profile image
Marc Lipovsky • Edited

HA That's pretty funny! I'm definitely into the history lesson. I'll check it out, thanks!

UPDATE: Actually skimmed that article on the history. Wow, it's amazing that disagreements and bureaucracy can really define how the the world uses Javascript (and other languages for that matter).

Collapse
 
schemetastic profile image
Rodrigo Isaias Calix

Yup, it was until some time after that I realized how powerful proxies can be, trust there is more to it than what appears. But the points you add in this post add even more to what I believed I could do with proxies, great!

Collapse
 
webreflection profile image
Andrea Giammarchi

many other use cases + secured JS out of the box in here: github.com/WebReflection/proxy-pan...

Collapse
 
marclipovsky profile image
Marc Lipovsky

Yes! I love seeing more examples of this API. It's hard to contextualized how an API like can be used. Thanks for sharing!

Collapse
 
mordechairoth profile image
mordechairoth • Edited

Nice and interesting article, I like how the author teaches how to use proxies just by giving many good examples, without actually saying how to use it.

Collapse
 
factordiceomar profile image
OmarC

Awesome post. Short, concise and informative. And I learned something new as well.

Collapse
 
starboysharma profile image
Pankaj Sharma

Thanks for sharing. The article is on the point.

Collapse
 
artydev profile image
artydev

Great thank you :-)