What are Proxies and Reflection?
You can create a proxy to use in place of another object (called the target) by calling new Proxy()
. The proxy virtualizes the target so that the proxy and the target appear to be the same object to functionality using the proxy.
Proxies allow you to intercept low-level object operations on the target that are otherwise internal to the JavaScript engine. These low-level operations are intercepted using a trap, which is a function that responds to a specific operation.
The reflection API, represented by the Reflect
object, is a collection of methods that provide the default behavior for the same low-level operations that proxies can override. There is a Reflect
method for every proxy trap. Those methods have the same name and are passed the same arguments as their respective proxy traps. Table 11-1 summarizes this behavior.
{title=”Table 11-1: Proxy traps in JavaScript”}
Proxy Trap | Overrides the Behavior Of | Default Behavior |
---|---|---|
get | Reading a property value | Reflect.get() |
set | Writing to a property | Reflect.set() |
has | The in operator | Reflect.has() |
deleteProperty | The delete operator | Reflect.deleteProperty() |
getPrototypeOf | Object.getPrototypeOf() | Reflect.getPrototypeOf() |
setPrototypeOf | Object.setPrototypeOf() | Reflect.setPrototypeOf() |
isExtensible | Object.isExtensible() | Reflect.isExtensible() |
preventExtensions | Object.preventExtensions() | Reflect.preventExtensions() |
getOwnPropertyDescriptor | Object.getOwnPropertyDescriptor() | Reflect.getOwnPropertyDescriptor() |
defineProperty | Object.defineProperty() | Reflect.defineProperty |
ownKeys | Object.keys , Object.getOwnPropertyNames() , Object.getOwnPropertySymbols() | Reflect.ownKeys() |
apply | Calling a function | Reflect.apply() |
construct | Calling a function with new | Reflect.construct() |
Each trap overrides some built-in behavior of JavaScript objects, allowing you to intercept and modify the behavior. If you still need to use the built-in behavior, then you can use the corresponding reflection API method. The relationship between proxies and the reflection API becomes clear when you start creating proxies, so it’s best to dive in and look at some examples.
I> The original ECMAScript 6 specification had an additional trap called enumerate
that was designed to alter how for-in
and Object.keys()
enumerated properties on an object. However, the enumerate
trap was removed in ECMAScript 7 (also called ECMAScript 2016) as difficulties were discovered during implementation. The enumerate
trap no longer exists in any JavaScript environment and is therefore not covered in this chapter.