1. An overview of the

Proxy is used to modify the default behavior of some operations, which is equivalent to making changes at the language level. Therefore, it is a kind of “metaprogramming”, that is, programming a programming language.

1.1 understand

Proxy creates a layer of interception in front of the target object. All external access to the object needs to pass through this layer. Therefore, access to the outside world is filtered and overwritten in interception.

In Es6, a native Proxy constructor is provided that can be used to generate a Proxy instance.

let proxy = new Proxy(target, handler)
Copy the code

All uses of the Proxy object are the same as above, except for the handler argument. The new Proxy() parameter represents the generation of a Proxy instance, the target parameter represents the target object of all interception, and the handler parameter is also an object used to customize interception behavior. As follows:

let proxy = new Proxy({}, {
    get: function(target, property) {
        return 35
    }
})

proxy.time // 35
proxy.name // 35
proxy.title // 35
Copy the code

Reading:

In the above, Proxy takes two arguments as a constructor. The first parameter is the target object that the operation would have accessed without Proxy intervention. The second argument is a configuration object that provides specific functions and interceptions for each proxy object operation. The above code includes a get function that intercepts access requests to properties of the target object.

In addition, for the Proxy to work, you must operate on the Proxy instance, not the target object.

If the handler does not set up any interceptions, that is equivalent to going straight to the original object. As follows:

let target = {}
let handler = {}
let proxy = new Proxy(target, handler)


proxy.a = 'b'
target.a = 'b'
Copy the code

For the above example, we can talk about Proxy objects and set them to the Object. Proxy property so that they can be called on object objects.

let object = {proxy: new Proxy(target, handler)}
Copy the code

Proxy instances can also serve as prototype objects for other objects.

let proxy = new Proxy({}, { get: Function (target, property) {retrun 35}}) let obj = object.create (proxy) obj. Time // 35Copy the code

Commonly used proxies support the following interception operations:

  • Get (target, propKey, receiver): Intercepts reading of object properties, such as proxy.foo and proxy[‘foo’]
  • Set (target, propKey, value, receiver): Intercepts the setting of object properties, such as proxy.foo = v or proxy[‘foo’] = v, and returns a Boolean value
  • Has (target, proKey): Intercepts the propKey in proxy operation and returns a Boolean value
  • Apply (target, object, args): intercepts operations called by Proxy instances as functions, such as Proxy (… The args), proxy. Call (object,… The args), proxy. Apply (…). .
  • DeleteProperty (target, proKey): Intercepts the operation of delete Proxy [propKey] and returns a Boolean value
  • OwnKeys (target) : interception Object. GetOwnProPertyNames (proxy), and returns an array. This method returns the property names of all of the target Object’s own properties, whereas object.keys () returns only the traversable properties of the target Object itself.

1.2 the get ()

The get method is used to intercept the read operation of an attribute. It can take three parameters: the target object, the attribute name, and the proxy instance itself. The last parameter is optional.

} let proxy = new proxy (p, {get: function(target, Property) {if (property in target) {retrun target[property]} else {console.log(' error ')}}}) proxy.name Proxy. age // 'error'Copy the code

Pay attention to the point

  • The GET method can be inherited
  • The get method can do chain operations

1.3 the set

The set method is used to intercept the assignment of an attribute and can take four parameters: the target object, the attribute name, the attribute value, and the Proxy instance itself. The last parameter is optional

let v = { set: function(obj, prop, value) { if (prop === 'age') { if(! Number.isinteger (value)) {console.log(' error ')} if(value > 200) {console.log(' success ')} obj[prop] = value}}} let p = new Proxy({}, v) p.age = 100 p.age // 100 p.age = 'n' p.age // An error was reportedCopy the code

With the set method, you can data bind, which means that the Dom is automatically updated every time an object changes

If a property of the target object itself is not writable or configurable, the Set method will not work.

1.4 the apply ()

The Apply method intercepts function calls, calls, and apply operations. It can take three arguments: the target object, the context object of the target object (this), and an array of the parameters of the target object.

let h = { apply(target, ctx, args) { return Reflect.apply(... arguments) } } let target = function() {return 'haha') let h = { apply: function() { return 'heihei' } } let p = new Proxy(taraget, h) p() // 'heihei'Copy the code

1.5 from the

The HAS method is used to intercept the HasProperty operation, which takes effect when determining whether an object has a property.

The HAS method can take two parameters, the target object and the name of the property to be queried.

Note: The HAS method intercepts the HasProperty operation, not the HasOwnProperty operation, i.e. the HAS method does not determine whether a property is an object’s own property or an inherited property.

1.6 the construct

Construct method is used to intercept the new command. Here’s how to write the intercept object

let h = { construct(target, args, newTarget) { retrun new target(... Args)}} target: target object args: constructor parameter object newTarget: constructor used by the new command when creating instance objectsCopy the code

1.7 deleteProperty ()

The deleteProperty method intercepts the DELETE operation. If the method throws an error or returns false, the current property cannot be deleted by the delete command.

2. This problem

Although Proxy can Proxy the access of the target object, it is not a transparent Proxy of the target object, that is, without any interception, it cannot guarantee the consistent behavior of the target object. The main reason is that in the case of Proxy, the this keyword inside the target object points to Proxy