What’s the point?
Proxy is an ECMAScript6 mechanism for developers to intercept internal operations on an object such as property access, assignment, enumeration, function invocation, etc. This allows a developer to alter the default behavior of an operation or to perform a custom side-effect. Proxies are used for:
- Logging and debugging
- Validation
- Data Binding
- Memoization (caching)
- Act as API wrapper
- Metaprogramming
- … and to achieve various other patterns.
Proxy and Reflect
Javascript provides a Proxy
object to allow a developer to intercept any low-level internal methods ([[set]], [[get]], [[hasProperty]], etc.)
via traps performed against a target object. These internal methods, denoted by double square brackets, are not directly accessible.
A Proxy object wraps a target object thus acting as a gatekeeper to intercept operations defined within a handler object.
Proxy’s kissing cousin, the reflection API, is a group of methods that reflect the default low-level behavior of an overridden trap.
A Reflect API method is typically called within a trap to access the internal default operation after altering default behavior
or performing a custom side-effect.
Just a note ...
All Proxy's traps have a corresponding `Reflect` **method** that accept the same arguments.
A list of internal methods and their corresponding traps can be found on MDNBy default, if a trap is not defined on the handler, then the operation will passthrough to the target. For example,
a proxy initialized with an empty handler will behave exactly as the target. It is possible to understand this by
defining get
, but not set
; therefore intercepting get
, but allowing set
to passthrough to the target.
Prior to ECMAScript 6, Object.defineProperty()
would allow you to intercept property access, albeit awkwardly. Proxy
simplifies this without having to directly modify or redefine access when new properties are set.
Examples
Validate a Property
Proxy can provide for a simple approach to object property validation. For example, if we have a need to validate a property for only a numeric value e.g. age, amount, count, we can define set within the handler to throw an exception if a value is not of type number.
Data Binding
A primitive example of data-binding can be demonstrated by observing the change
of a proxied array via a callback. This is conceptually similar to watch()
in Vue.js.