Overview
Proxy and Reflect are APIs introduced by ES6 for operating on objects.
Proxy can intercept operations on the target object, such as reading and function calls, and then perform operation processing. It does not directly operate on the object, but like the proxy pattern, it operates through a proxy object of the object, and during these operations, additional required operations can be added.
Reflect can be used to obtain the behavior of the target object. It is similar to Object, but more readable, providing a more elegant way to operate on objects. Its methods correspond to Proxy.
Basic Usage
Proxy
A Proxy object consists of two parts: target and handler. When creating an instance object through the Proxy constructor, these two parameters need to be provided. target is the target object, and handler is an object that declares the specified behavior for proxying target.
Instance Methods
get(target, propKey, receiver)
Used for the read operation of propKey on the target object.
The get() method can be inherited.
set(target, propKey, value, receiver)
Used to intercept the assignment operation of propKey on the target object. If a property of the target object itself is non-writable and non-configurable, then the set method will have no effect.
The fourth parameter receiver represents the object where the original operation behavior is located, generally the Proxy instance itself.
Note: in strict mode, if the set proxy does not return true, an error will be reported.
apply(target, ctx, args)
Used to intercept function calls, call, and reply operations. target represents the target object, ctx represents the target object context, and args represents the argument array of the target object.
has(target, propKey)
Used to intercept the HasProperty operation, that is, when determining whether the target object has the propKey property, it will be intercepted by this method. This method does not determine whether a property is an object's own property or an inherited property.
Note: This method does not intercept for...in loops.
construct(target, args)
Used to intercept the new command. The return value must be an object.
deleteProperty(target, propKey)
Used to intercept the delete operation. If this method throws an error or returns false, the propKey property cannot be deleted by the delete command.
defineProperty(target, propKey, propDesc)
Used to intercept Object.definePro. If the target object is non-extensible, adding a property that does not exist on the target object will report an error; if a property is non-writable or non-configurable, these properties cannot be changed.
erty operation
getOwnPropertyDescriptor(target, propKey)
Used to intercept Object.getOwnPropertyD(). The return value is a property descriptor object or undefined.
ptor property
getPrototypeOf(target)
Mainly used to intercept operations that get the object prototype. Includes the following operations:
- Object.prototype._proto_ - Object.prototype.isPrototypeOf() - Object.getPrototypeOf() - Reflect.getPrototypeOf() - instanceof
Note: the return value must be an object or null, otherwise an error will be reported. In addition, if the target object is non-extensible, the getPrototypeOf method must return the prototype object of the target object.
isExtensible(target)
Used to intercept the Object.isExtensible operation.
This method can only return a boolean value; otherwise, the return value will be automatically converted to a boolean.
Note: its return value must be consistent with the isExtensible property of the target object, otherwise an error will be thrown.
ownKeys(target)
Used to intercept the read operation of an object's own properties. Mainly includes the following operations:
- Object.getOwnPropertyNames() - Object.getOwnPropertySymbols() - Object.keys() - or...in
The array members returned by the method can only be strings or Symbol values, otherwise an error will be reported.
If the target object contains non-configurable properties, these properties must be returned in the result, otherwise an error will be reported.
If the target object is non-extensible, it must return all and only all properties contained in the target object; it cannot include non-existent properties, otherwise an error will also be reported.
preventExtensions(target)
Intercept the Object.preventExtensions operation.
This method must return a boolean value, otherwise it will be automatically converted to a boolean.
setPrototypeOf
Mainly used to intercept the Object.setPrototypeOf method.
The return value must be a boolean, otherwise it will be automatically converted to a boolean.
If the target object is non-extensible, the setPrototypeOf method must not change the prototype of the target object.
Proxy.revocable()
Used to return a revocable Proxy instance.
Reflect
In ES6, some methods of Object that clearly belong to the language internals were moved to the Reflect object (currently some methods exist on both the Object and Reflect objects), and future new methods will be deployed only on the Reflect object.
The Reflect object has modified the return results of some methods to make them more reasonable.
The Reflect object uses functions to implement Object's imperative operations.
Static Methods
Reflect.get(target, name, receiver)
Find and return the name property of the target object.
Reflect.set(target, name, value, receiver)
Set the name property of target to value. The return value is boolean; true indicates success, false indicates failure. When target is a non-existent object, an error will be reported.
Reflect.has(obj, name)
It is the functional form of the name in obj operator, used to check whether the name property exists in the obj object. The return value is boolean. If obj is not an object, a TypeError will be reported.
Reflect.deleteProperty(obj, property)
It is the functional form of delete obj[property], used to delete the property property of the obj object. The return value is boolean. If obj is not an object, a TypeError will be reported.
Reflect.construct(obj, args)
Equivalent to new target(...args).
Reflect.getPrototypeOf(obj)
Used to read the _proto_ property of obj. When obj is not an object, it does not convert obj to an object like Object does, but instead reports an error.
Reflect.setPrototypeOf(obj, newProto)
Used to set the prototype of the target object.
Reflect.apply(func, thisArg, args)
Equivalent to Function.prototype.apply.call(func, thisArg, args). func represents the target function; thisArg represents the this object bound to the target function; args represents the argument list passed when the target function is called, which can be an array or an array-like object. If the target function cannot be called, a TypeError is thrown.
Reflect.defineProperty(target, propertyKey, attributes)
Used to define properties for the target object. If target is not an object, an error is thrown.
Reflect.getOwnPropertyDescriptor(target, propertyKey)
Used to obtain the descriptor object of the propertyKey property of the target object. When target is not an object, an error is thrown to indicate an invalid parameter; the non-object is not converted to an object.
Reflect.isExtensible(target)
Used to determine whether the target object is extensible. The return value is a boolean. If the target parameter is not an object, an error is thrown.
Reflect.preventExtensions(target)
Used to make the target object non-extensible. If the target parameter is not an object, an error is thrown.
Reflect.ownKeys(target)
Used to return all properties of the target object, equivalent to the combination of Object.getOwnPropertyNames and Object.getOwnPropertySymbols.
Combined Use
The methods of the Reflect object correspond one-to-one with the methods of the Proxy object. Therefore, the methods of the Proxy object can obtain default behavior by calling the methods of the Reflect object, and then perform additional operations.
Expanded Use Cases
Implementing the Observer pattern.