Home  >  Article  >  Web Front-end  >  Why must Reflect be used for Proxy in vue3?

Why must Reflect be used for Proxy in vue3?

PHPz
PHPzforward
2023-06-01 18:55:061409browse

Those who have used vue know that vue's response implementation uses Proxy, and it is used with Reflect. The most obvious thing when looking at the Proxy and Reflect documents is that the static method of the Reflect object has the same name as the Proxy proxy method, and Reflect can operate it. Object use, proxy can proxy objects, but I didn’t find out why sometimes Reflect must be used in the Proxy proxy method

Basic operations

The static method of the Reflect object has the same name as the Proxy proxy method. There are 13 types. Examples of get and set are as follows

const tempObj = { a: 1 };
Reflect.get(tempObj, 'a'); // 返回 1
Reflect.set(tempObj, 'a', 2); // 返回true 表示设置成功, a的值变2

const tempObj1 = { a: 1 };
const handler = {
  get: function (obj, prop, receiver) {
    return prop === 'a' ? 1000 : obj[prop];
  },
  set: function (obj, prop, value, receiver) {
    console.log(prop);
    obj[prop] = prop === 'a' ? 6 : value;
    return true;
  },
};
const proxyObj = new Proxy(tempObj1, handler);
proxyObj.a; // proxyObj => {a: 1000}
proxyObj.a = 2; // proxyObj => {a: 6}

Question

If the Proxy does not perform other operations and returns directly normally

const tempObj1 = { a: 1 };
const handler = {
  get: function (obj, prop, receiver) {
    return obj[prop];
  },
  set: function (obj, prop, value, receiver) {
    obj[prop] = value
    return true;
  },
};
const proxyObj = new Proxy(tempObj1, handler);
proxyObj.a; // proxyObj => {a: 1}
proxyObj.a = 2; // proxyObj => {a: 2}

In the above situation, the Proxy can be completed without Using Reflect to handle interception is much simpler than using Reflect

Different objects, objects with get

const tempObj1 = {
  a: 1,
  get value() {
    console.log(this === proxyObj); // false
    return this.a;
  },
};
const handler = {
  get: function (obj, prop, receiver) {
    return obj[prop];
  },
  set: function (obj, prop, value, receiver) {
    obj[prop] = value;
    return true;
  },
};
const proxyObj = new Proxy(tempObj1, handler);
proxyObj.value; // 1

The printed value in the above value is false, The expected result should be true, but the value of the original object used in the proxy should be taken, so this points to the original object, so the value is false

Although this points to the wrong value, the value obtained is still correct. This It’s not a certain reason

const parent = {
  a: 1,
  get value() {
    console.log(this === child); // false
    return this.a;
  },
};
const handler = {
  get: function (obj, prop, receiver) {
    return obj[prop];
  },
  set: function (obj, prop, value, receiver) {
    obj[prop] = value;
    return true;
  },
};

const proxyObj = new Proxy(parent, handler);
const child = Object.setPrototypeOf({ a: 2 }, proxyObj);
child.value; // 1

There is a problem. The output results are different from what is expected. This should point to the child, but it points to the parent

Reflect

If Reflect.get(obj, prop) is replaced by obj[prop], it means there is no change. The meaning and result are the same. Isn’t this still There is a receiver parameter that is useless.

const parent = {
  a: 1,
  get value() {
    console.log(this === child); // true
    return this.a;
  },
};
const handler = {
  get: function (obj, prop, receiver) {
    Reflect.get(obj, prop)
   - return obj[prop];
   + retrun Reflect.get(obj, prop, receiver)
  },
  set: function (obj, prop, value, receiver) {
   - obj[prop] = value;
   + Reflect.get(obj, prop, value, receiver)
    return true;
  },
};

const proxyObj = new Proxy(parent, handler);
const child = Object.setPrototypeOf({ a: 2 }, proxyObj);
child.value; // 2

this points to the correct point, and the result is of course consistent with expectations. receiver does not refer to the proxy object, nor does it It refers to the original object, but the execution context (there is a saying that without changing this in a specific way, whoever calls points to whom, this is what is expected), here child is called valueSo the expected pointer should be child. Here you may think of using receiver[prop] directly, but that won’t work. This will cause execution overflow, receiver[prop] Equivalent to child.value, child.value has not been executed yet, receiver[prop] is executed again, and it will continue to execute indefinitely

Reflect.get(target, key, receiver)The receiver parameter in #Reflect.get(target, key, receiver) has been modified to point to this, without adding this points to target, and after adding it points to receiver

is useful in the proxy object this You must use Reflect

, so that you can always get the expected value

Summary

The proxy objects in vue3 all get the expected values. Values ​​are collected and updated during interception, so be sure to use Reflect in the interception function of Proxy

#How to always get the expected value? Being an agent is like not having an agent###
  get: function (...arg) {
    return Reflect.get(...arg);
  },

The above is the detailed content of Why must Reflect be used for Proxy in vue3?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete