Detailed use of Proxy-Reflect

If you just want to be an ordinary developer, you may not have a thorough understanding of these two, but if you want to be a framework or component developer, you need to have a deeper understanding of them.

1. Monitor the operation of the object

Now there is a requirement: there is an object, and we want to monitor the process of setting or getting properties in this object.

We can monitor the operation of the property through the stored property descriptor of Object.defineProperty . In fact, the responsive principle of vue2 is similar to this.

const obj1 = {
        name: "name",
        age: "age"
      }

      Object.keys(obj1).forEach(key => {
        let value = obj1[key]
        Object.defineProperty(obj, key, {
          set: function(newValue) {
            console.log(`监听到给${key}设置值`);
            value = newValue
          },
          get: function(){
            console.log(`监听到获取${key}值`);
            return value
          }
        })
      })

Disadvantages of doing this:

  • First of all, the original intention of Object.defineProperty is not to monitor all properties in an object. When we define some properties, the original intention is to define ordinary properties, but later we force it into a data property descriptor.
  • Secondly, if we want to monitor richer operations, compare new properties, delete properties, then Object.defineProperty is helpless.

So ES6 has added a Proxy class.

2. Basic use of Proxy

The Proxy class is used to help us create a proxy.

  • If we want to monitor the related operations of an object , we can first create a proxy object (Proxy object);
  • All subsequent operations on the object are done through the proxy object, and the proxy object can monitor what operations we want to perform on the original object.

First of all, we need a new Proxy object , and pass in the object to be listened to and a processing object , which can be called a handler .

const proxy = new Proxy (target, handler) //Syntax

Our subsequent operations are all operations on the Proxy , not the original object, because we need to listen in the handler .

const obj = {
name: "zzz",
age: "18"
}

const proxy = new Proxy(obj, {})

3. Proxy's set and get captures

If we want to listen to some specific operations, we can add corresponding traps (Trap) to the handler :

set and get respectively correspond to the function type ;

The set function has four parameters:

  • target: target object (listening object);
  • property: the property key to be set;
  • value: new attribute value;
  • receiver: the proxy object to call;

The get function has three parameters:

  • target: target object (listening object);
  • property: the acquired property key;
  • receiver: the proxy object to call;
const obj1 = {
        name: "name",
        age: "age"
      }

      const proxy = new Proxy(obj1, {
        has: function(target, key) {
          console.log("has捕捉器", key)
          return key in target
        },
        set: function(target, key, value) {
          console.log("set捕捉器", key)
          target[key] = value
        },
        get: function(target, key) {
          console.log("get捕捉器", key)
          return  target[key]
        },
        deleteProperty: function(target, key) {
          console.log("delete捕捉器")
          delete target[key]
        }
      })
      proxy.name = "sss"

If you want to modify the object later, you can do it by operating the proxy object, and you can listen to the object.

4. All captures of Proxy

handler.getPrototypeOf()
  • Catcher for the Object.getPrototypeOf method.
handler.setPrototypeOf()
  • Catcher for the Object.setPrototypeOf method.
handler.isExtensible()
  • The catcher of the Object.isExtensible method (judging whether new properties can be added).
handler.preventExtensions()
  • Catcher for the Object.preventExtensions method.
handler.getOwnPropertyDescriptor()
  • Catcher for the Object.getOwnPropertyDescriptor method.
handler.defineProperty()
  • Catcher for the Object.defineProperty method.
handler.ownKeys()
  • Catcher for Object.getOwnPropertyNames method and Object.getOwnPropertySymbols method.
handler.has()
  • Catcher for the in operator.
handler.get()
  • Catcher for property read operations.
handler.set()
  • Catcher for property setting operations.
handler.deleteProperty()
  • Catcher for the delete operator.
handler.apply()
  • Catcher for function call operations.
handler.construct()
  • Catcher for the new operator.

5. Proxy construct and apply

There are also construct and apply in the catcher, which are applied to function objects

6. The role and use of Reflect

Reflect is a new API of ES6, which is an object , which literally means reflection.

It mainly provides many methods for manipulating Javascript objects , a bit like the methods for manipulating objects in Object ;

  • For example, Reflect.getPrototypeOf(target) is similar to Object.getPrototypeOf();
  • For example, Reflect.defineProperty(target, propertyKey, attributes) is similar to Object.defineProperty();

If we have Objects that can do these operations, why do we need new objects like Reflect?

  • This is because in the early ECMA specification, it was not considered how to design the operation of the object itself to be more standardized , so these APIs were placed on Object ;
  • But Object is a constructor , these operations are actually not suitable for it ;
  • In addition, it also contains some operators similar to in and delete , which makes JS look a little strange;
  • Therefore, Reflect was added in ES6 , allowing us to concentrate these operations on the Reflect object;
  • In addition, when using Proxy, you can do not operate the original object ;
const obj1 = {
        name: "name",
        age: "age"
      }

      const proxy = new Proxy(obj1, {
        has: function(target, key) {
          console.log("has捕捉器", key)
          return Reflect.has(target, key)
        },
        set: function(target, key, value, receiver) {
          console.log("set捕捉器", key)
          return Reflect.set(target, key, value, receiver)
        },
        get: function(target, key, receiver) {
          console.log("get捕捉器", key)
          return Reflect.get(target, key, receiver)
        },
        deleteProperty: function(target, key) {
          console.log("delete捕捉器")
          return Reflect.deleteProperty(target, key)
        }
      })
We found that there is a receiver parameter when using getter and setter . What is its function?
  If our source object (obj) has setter and getter accessor properties , then the this inside can be changed through the receiver ;

7. Common methods of Reflect

◼ Reflect.getPrototypeOf(target)
Similar to Object.getPrototypeOf().
Reflect.setPrototypeOf(target, prototype)
A function to set the prototype of the object. Returns a Boolean, if the update is successful, it returns
true。
Reflect.isExtensible(target)
Similar to Object.isExtensible()
Reflect.preventExtensions(target)
Similar to Object.preventExtensions(). Returns a Boolean.
Reflect.getOwnPropertyDescriptor(target, propertyKey)
Similar to Object.getOwnPropertyDescriptor(). If the object exists
If the attribute, returns the corresponding attribute descriptor, otherwise returns undefined.
Reflect.defineProperty(target, propertyKey, attributes)
Similar to Object.defineProperty(). If the setting is successful, it will return true
Reflect.ownKeys(target)
Returns an array containing all own properties (excluding inherited properties). (similar to
Object.keys(), but not affected by enumerable).
Reflect.has(target, propertyKey)
Judging whether an object has a certain attribute, the function is exactly the same as that of the in operator.
Reflect.get(target, propertyKey[, receiver])
Get the value of a property on the object, similar to target[name].
Reflect.set(target, propertyKey, value[, receiver])
A function that assigns a value to an attribute. Returns a Boolean, true if the update was successful.
Reflect.deleteProperty(target, propertyKey)
As the delete operator of the function, it is equivalent to executing delete target[name].
Reflect.apply(target, thisArgument, argumentsList)
Call a function, and at the same time, you can pass in an array as a call parameter. and
Function.prototype.apply() functions similarly.
Reflect.construct(target, argumentsList[, newTarget])
Performing new operation on the constructor is equivalent to executing new target(...args).

Guess you like

Origin blog.csdn.net/m0_51636525/article/details/125468300