>  기사  >  웹 프론트엔드  >  vue3에서 Proxy에 Reflect를 사용해야 하는 이유는 무엇입니까?

vue3에서 Proxy에 Reflect를 사용해야 하는 이유는 무엇입니까?

PHPz
PHPz앞으로
2023-06-01 18:55:061407검색

Vue를 사용해본 사람들은 Vue의 응답 구현이 Proxy를 사용하고 Reflect와 함께 사용된다는 것을 알고 있습니다. Proxy 및 Reflect 문서를 볼 때 가장 눈에 띄는 것은 Reflect 개체의 정적 메서드가 Proxy 프록시와 동일한 이름을 가지고 있다는 것입니다. Reflect는 객체를 조작하는 데 사용할 수 있습니다. 프록시는 객체를 프록시할 수 있지만 때때로 프록시 프록시 메소드에서 Reflect를 사용해야 하는 이유를 찾지 못했습니다.

기본 작업

Reflect 객체의 정적 메소드는 동일한 이름을 갖습니다. Proxy Proxy 메소드로 13가지 종류가 있으며, get과 set의 예시는 다음과 같습니다

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

Proxy가 다른 작업을 하지 않고 직접 반환하는 경우

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}

위 상황에서 Proxy는 별도의 조치 없이 차단을 처리할 수 있습니다. Reflect를 사용하는 것보다 훨씬 간단합니다. 값이므로 원래 개체를 가리키므로 값이 거짓입니다

잘못된 개체를 가리킨다고는 하지만 여전히 값이 정확하지는 않습니다

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

문제가 있습니다. 출력 결과가 예상과 다름 >obj[prop]. 의미와 결과는 동일합니다. 그럼 쓸모없는 다른 수신자 매개변수는 없나요? 결과는 물론 예상과 일치합니다. receiver은 프록시 객체나 원본 객체를 참조하지 않고 실행 컨텍스트를 참조합니다(문장은 다음과 같습니다. 특정 방식으로, 누가 누구를 가리키는지, 이것이 예상되는 것입니다. 여기서 child을 호출하므로 예상되는 지점은 child여야 합니다. > 여기서는 receiver[prop]를 직접 사용한다고 생각할 수 있지만 이렇게 하면 실행 오버플로가 발생합니다. child.value, child.value는 아직 실행되지 않았으며 receiver[prop]가 다시 실행되어 무한정 계속 실행됩니다

Reflect.get(target, key, receive)receiver 매개변수는 this를 추가하지 않고 this 포인터를 수정합니다. target을 가리킨 다음 receiver

프록시 개체에서 this를 사용할 때는 를 사용해야 합니다. 반영 code> 이런 방식으로 우리는 항상 예상 값을 얻을 수 있습니다<p></p> <p>Summary<code>Reflect.get(obj, prop)换成obj[prop],这等于没换,意义和结果是一样的,这不是还有一个receiver参数没有用嘛

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

this指向正确,结果也当然和期望一致,receiver的不是指代理对象,也不是指原对象,而是执行上下文(有句话是这么说的,不用特定方式改变this的情况下,谁调用指向谁,这就是期望的),这里child调用的value所以期望的指向应该是child, 这里你可能想到直接用receiver[prop]不行了,这样会出现执行溢出,receiver[prop]相当于child.valuechild.value还没执行完,receiver[prop]又执行了,就会无限在执行

Reflect.get(target, key, receiver)中的receiver参数修改了this指向,不加this指向target, 加了后指向receiver

代理对象中有用到this时一定要用到Reflect,这样才能得到一直符合期望的值

总结

vue3中的代理对象到得的都是符合期望的值,在拦截中做了收集和更新,所以一定要在Proxy的拦截函数中使用Reflect

vue3의 프록시 객체는 가로채기에서 예상 값을 수집하고 업데이트하므로 반드시 Proxy의 가로채기 기능에 <code>Reflect를 사용하여 처리합니다

항상 기대값을 얻는 방법은 Proxy가 없는 것과 같습니다🎜
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

위 내용은 vue3에서 Proxy에 Reflect를 사용해야 하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제