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
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
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
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
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"
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)
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.
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.
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!
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
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!
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/
Love Increment! Thanks for sharing this I keep finding more advanced uses and might do a follow up.
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.
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!
I really enjoyed this post, it was clear and straightforward.
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
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).
many other use cases + secured JS out of the box in here: github.com/WebReflection/proxy-pan...
Yes! I love seeing more examples of this API. It's hard to contextualized how an API like can be used. Thanks for sharing!
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.
Awesome post. Short, concise and informative. And I learned something new as well.
Thanks for sharing. The article is on the point.