The goal of the Proxy API is to extend JS meta-programming capabilities. Meta-programming is a programming technique that lets you alter your program’s behavior, analyze its internals and even change the source code on the fly. Proxy API lets you override JS internal operations, such as object property lookup, enumeration, assignment, iteration, function invocation, generators behavior and much more.
The basic terminology of the Proxy API includes these terms:
Traps are the methods you are overriding. Here is the full list of possible traps, i.e. the list of functions that you can override using the Proxy API:
- Object methods:
- Property getters/setters:
- Function methods:
Handler is an object, whose properties are traps. This means you can define multiple traps on one handler!
Target is an object whose methods are overridden. It can be any object, meaning you can apply proxies to third-party modules, built-in objects and even the Proxy object itself!
Using the GET trap
Now, let’s look at some examples. The easiest one I could think of is using the
get trap to provide default values for undefined properties:
You can see that on lines 1–4 we create a handler for the proxy. It has a
get function defined, which overrides the property lookup behavior. In case a property is not defined on the object, we return
'general kenobi' instead of undefined. Then, on line 6 we use the Proxy API to make that happen. Note the
new keyword, it is required as
Proxy is a constructor function. Lastly, on lines 10-11 you can see our proxy in action: for the non-existent
'hello there' property, the default value of
'general kenobi' is returned.
Using the SET trap
Now let’s move to a more advanced example. We will use the
set trap to (1) validate the property value to make sure its a string, and (2) convert the string to uppercase. Here is the code:
Now we use the
set trap in the handler to override the property assignment behavior. It first checks if the value is a string, and, if it is, saves an upper case version on the object with the specified key. You can see how it behaves on lines 13-15: throws if you try to pass
5 and converts