How to use JavaScript Proxies for Fun and Profit

Alberto Gimeno
Jan 22, 2018 · 5 min read

There’s a very recent new feature of the JavaScript language that is still not being widely used: JavaScript proxies.

With JavaScript proxies you can wrap an existing object and intercept any access to its attributes or methods. Even if they do not exist! 💥

You can intercept calls to methods that do not exist

👋 Hello World Proxy

Let’s start with the basics. A ‘hello world’ example could be:

Which outputs:

In this example we just do something before accessing the property / method. But then we return the original property or method.

You can also intercept changes to properties by implementing a set handler.

This could be useful to validate attributes or things like that. But I think this feature is a lot more promising. I hope new frameworks will arise that will use proxies for its core functionality. I’ve been thinking about it and these are some ideas:

🚀 An SDK for an API with 20 lines of code

As I said, you can intercept method calls for methods that… don’t even exist. When somebody calls a method on a proxied object the get handler will be called and then you can return a dynamically generated function. You don’t have to touch the proxied object if you don’t need to.

With that idea in mind, you can parse the method being invoked and dynamically implement its functionality in runtime! For example we could have a proxy that when invoked with api.getUsers() it could make a GET /users in an API. With this convention we can go further and api.postItems({ name: ‘Item name' }) would call POST /items with the first parameter as request body.

Let’s see a full implementation:

Here the proxied object is just {} because all methods are dynamically implemented. We don’t actually need to wrap a functional object.

You’ll see that some methods have an $ This is a placeholder for inlined parameters.

If you don’t like that, it could be implemented in a different way. 🙂

Side note: These examples can be optimized. You could cache the dynamically generated function in a hash object instead of returning a new function every time. But for clarity I left it like that for the examples.

📦 Querying data structures with more readable methods

What if you had an array of people and you could do:

Sure you can with proxies! We can implement a proxy that wraps an array, parses method calls and does queries like that one.

I’ve implemented a few possibilities here:

It would be super similar to write an assertion library like expect using proxies.

Another idea would be to create a library to query databases with an API like this:

📊 Monitoring async functions

Since you can intercept method calls, if a method call returns a promise you can also track when the promised is fulfilled. With that idea I made a quick example of monitoring the async methods of an object and printing some statistics in the command line.

You have a service like the following one and with one method call you can wrap it:

This is a full example:

JavaScript proxies are super powerful. ✨

They add a little overhead but on the flip side having the ability to dynamically implement methods at runtime by their name makes the code super elegant and readable. I haven’t done any benchmarks yet, but if you plan to use them in production I would do some performance testing first.

However, there’s no problem of using them on development, like the monitoring of async functions for debugging!

DailyJS

JavaScript news and opinion.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store