Proxy and reflect in JavaScript

created: 14 hours ago
updated: 14 hours ago
new
  • language
  • syntax
  • apis

Intro

Learn the difference between Proxy and Reflect and their useful use cases.

Have you ever wondered how to interact with code written by other programmers without intruding on their code?
There is something called
metaprogramming
. Thanks to it you can achieve it.
Two objects will help you:
Proxy
and
Reflect
. Today you will learn how, when, and where you can use them to master a powerful technique.
Metaprogramming is not invented by
Meta
company 🤡.
1. Metaprogramming
To start talking about metaprogramming, you need to answer the question: what is data and code? Every programming language has both of these but what do they mean, exactly?
Data
can be for example:
Code
is an expression - an instruction to be executed on this data. It can be:
const result = 1 + (2 * 3)
.
At first glance, you can say that it is a mathematical expression, and this is indeed the case if we are talking about the field of mathematics. However, according to the presented approach, we will consider it in two ways:
From this it follows that the same representation of an expression can have different interpretations. This approach is what metaprogramming is all about.
Knowing this is a powerful tool for building data and expressions. It allows us to create functions that multiply data which means we can write programs that write programs. It is a certain level of abstraction.
To illustrate this more easily, let's discuss it with this example:
According to the data it is a plain text, but according to the code it is something to be interpreted as an instruction, so:
Congratulations, you have just successfully interpreted a piece of code through metaprogramming!
2. Proxy pattern explained
A
proxy
is a
structural design pattern
that allows you to create a proxy object in place of another object. A proxy is a kind of guardian that protects access to the original object, or changes its behavior.
How do you translate this into a simple example from life?... Cash! Cash is the physical representation of the capital placed in your bank account. But what about it? Have you ever used a credit card?
Well, think about it. Credit card is an actually proxy for your cash in the bank. You don't need to physically have paper money with you to buy something. Both of these entities implement the same interface (you can perform an action with them - pay). At the same time, you are actually operating an object that protects another object (in the bank).
3. Proxy in JavaScript
Let's start with a simple example for reference:
As you can see, we have overwritten the
get
mechanism for reading the properties for the
ProtectedObject
without interfering with its implementation. Now reading a property separated by the symbol "_", you are able to transform several properties into a string of characters.
Even more can be achieved by overwriting
set
behavior. Just look at this:
We added validation which makes sense. Who normally tries to add something to an object with a certain shape?
When does a proxy make sense? The proxy should totally replace the target object everywhere. No one should ever reference the target object after it got proxied. Otherwise it’s easy to mess up.
4. Proxy use cases
Logging access to an object:
Custom error handling/validation:
Protect the object field:
Lazy initialization:
5. What is Reflection?
Reflection is a closely related concept to object-oriented programming. Among other things, it is used to check the properties of a
class/object/method
. This technique allows building more dynamic functionality that is native to a particular programming language.
Languages that use this functionality are able to modify their own environment. So the use of reflection should be thoughtful and used only in specific cases to avoid messy effects.
6. Reflect feature in JavaScript
Reflect
is a Javascript native object that provides methods same as proxy feature. It is not a functional object, so its methods are static (not constructable). What does this mean? We can't create an instance of a Reflect object through the
new
operator or call it like a function.
So which approach should I use? In my opinion:
both
.
Proxy provides us with a number of options for changing an object's behavior during particular actions, while Reflect gives us access to their default behavior.
It is a modified example "Protect the object field":
Simpler? Clearer? Without an additional condition? Of course it is.
Besides, the Reflect object provides us with a lot of functionality, which can be categorized as "syntax sugar".
7. Reflect use cases
Need to find out if an object has a field?
Need to return all the keys of an object?
Want to add a new field? No problem!
I hope you now understand Proxy and Reflect 🧑‍💻. I must say, they are tricky, yet useful and powerful.
Next time when you see an ugly, old legacy code remember that you have these API's and there may be a good use case for them.
Feel free to contact me if you have any questions/proposals. Have a nice day and good health!