Analysis of ES6 Proxy

1 About Proxy

Proxy, proxy, is a feature introduced by ES6. Through Proxy, we can intercept certain operations of the object and add customized code to make these operations more abundant and flexible

grammar:

let proxy = new Proxy(target,handle)

Proxy represents the class that creates the proxy instance, target is the object being proxied, handle is the interceptor object, and contains interceptor methods

2 Proxy commonly used API

  • set intercept attribute write
  • get intercept attribute reading
  • deleteProerty intercept property deletion
  • has intercept in operator
  • revocable Cancel proxy
    ...

2.1 Proxy api example: set

Proxy has many methods, here is the most representative set method as an example

In Proxy Handle, set is used to intercept the attribute assignment operation of the target object. The
set has four parameters, which are the proxy object target, the attribute name key, the attribute value value, and the caller receiver of the set method (analogous to this generally pointing to the call Obj), this receiver is generally a proxy, but there are exceptions, which will be explained later

After the proxy, once the object attribute is assigned through the proxy, the set (if any) in the proxy will be executed. Otherwise, it will not, that is, assigning a value directly to the object will not trigger the Proxy set method

let person = {
    
    name:'island'}
let proxy = new Proxy(person,{
    
    
    set(target,key,value,receiver){
    
    
        console.log('set run')
        return Reflect.set(target,key,value,receiver)
    }
})
proxy.name = 'proxy set'  // set run
person.name = 'person set' // nothing happen

The target must be the proxy object. The receiver is generally the proxy object proxy, but it is actually the caller of the set method.

let person = {
    
    name:'island'}
let proxy = new Proxy(person,{
    
    
    set(target,key,value,receiver){
    
    
        console.log(target === person) // true
        console.log(receiver === proxy ) // true 
    }
})
proxy.name = 'person set'

If the proxy is written to the prototype of the person, when the attributes are set for the person at this time, js will find the set from the person itself to the prototype chain and execute it. At this time, the caller of the set is person instead of peoxy, and the corresponding receiver also changes. Become a person, so we say that the receiver is the caller of the set method and not necessarily the proxy

let person = {
    
    };
let proxy = new Proxy({
    
    }, {
    
    
    set(target, prop, value, receiver) {
    
    
        console.log(receiver === person) // true
        console.log(receiver === proxy) // false
    }
});
Object.setPrototypeOf(person, proxy);
person.name = 'island'

note:

  • The set method can only work on the writable attribute of the target (writable is true), and the set is invalid when the writable is false
  • It is not recommended to assign attributes to the receiver in the set method, because this will repeatedly trigger the set execution and throw a function execution stack overflow exception. For the same reason, we don’t recommend doing attribute read operations on the receiver in the get method.
let person = {
    
    name:'isand'};
let proxy = new Proxy(person, {
    
    
    set: function (target, prop, value, receiver) {
    
    
        receiver[prop] = value //  Maximum call stack size exceeded

    },
    get(target,key,receiver){
    
    
        receiver[key] //  Maximum call stack size exceeded
    }
});
proxy.name = 'yoke'

3 Proxy application

With its own rich and flexible characteristics, Proxy can be used in many development scenarios and used
in engineering. The front end is the bridge between UI and background data. A scenario we often encounter is to format the timestamp in the interface data to show the user. , Or perform reasonable verification on the input of the form, and these can be done through the Proxy proxy

4 The relationship between Proxy and the proxy object

Whether it is to change the attributes of the proxy object target through the Proxy, or directly change the attributes of the operated object target, feedback can be obtained in the Proxy object and the target. Regarding the relationship between Proxy and target, I have always been puzzled. Some people tend to think that it is a shallow copy, but I don't think it is. If it is a shallow copy, when the properties of a non-reference type are changed, it will not affect the memory of the other party. But the facts are clearly contrary to it. Whether you change proxy.string or target.string, you can see the effect on the other party, so the relationship between the two is not a shallow copy.
For the time being, I think the relationship between Proxy and target is capable of accessing the same memory, but it is not an assignment reference, because the proxy === target value is false. This question is for the time being. You may have to wait to read the V8 implementation in the future, or someone in the community can read the V8 related implementation and share it with the outside world to get an explanation.

5 Differences between Proxy and Object.defineProperty

Object.defineProperty also has get and set methods, which have a part in common with Proxy. Object.defineProperty is used in Vue2.0 for data hijacking and two-way data binding. However, in Vue3.0, you have rewritten this feature with Proxy, which has to arouse everyone's discussion about the difference between Proxy and Object.defineProperty.

Semantically speaking, defineProperty focuses on the permissions when the property is manipulated, such as whether the property can be modified – writable, and whether it can be configured – configurable. And Proxy is more concerned about the behavior when the property is manipulated, such as what should be done before the object property is traversed – has, what should be done before being deleted – deleteProerty

In terms of details, Proxy monitors properties in more depth. Define an attribute value as an array. For Proxy, changes in the internal elements of the array will also be heard, triggering a set trap. The defineProperty's set is only executed when the attribute pointing to the address changes, and the change of the internal elements of the array will not be detected. It is precisely because of this feature of defineProperty that Vue2.0 needs to rewrite the push on the array prototype. , Splice and other methods

let arrProxy = new Proxy([], {
    
    
    set(target, key, value, receiver) {
    
    
        console.log('run Proxy set')
    }
})

let target = {
    
    }
Object.defineProperty(target,'arr',{
    
    
    set:function(){
    
    
        console.log('run defineProperty set ')
    }
})

arrProxy.push(1) // run Proxy set
target.arr.push(1) // nth happpen

Guess you like

Origin blog.csdn.net/qq_41109610/article/details/114558818