Регистрируйте, что получает получатель с помощью прокси - PullRequest
1 голос
/ 09 мая 2020

У меня есть следующий обработчик прокси, который регистрирует события.

const proxyHandler = {
  get: function(target, prop) {
    console.log("get", prop);
    return Reflect.get(target, prop);
  }
};

const obj = new Proxy(
  {
    value: 4,
    text: "hi",
    get textVal() {
      return this.text.repeat(this.value);
    },
    getTextVal() {
      return this.text.repeat(this.value);
    }
  },
  proxyHandler
);


console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);

Когда я регистрирую console.log(obj.getTextVal()), я получаю:

get getTextVal 
get text 
get value 
hihihihi 

Но когда я регистрирую геттер console.log(obj.textVal), я получаю только следующее:

get textVal 
hihihihi 

Как я могу заставить obj.textVal регистрировать get text и получать get value события с помощью прокси? ie. При запуске console.log(obj.textVal) я бы хотел получить следующий результат.

get getTextVal 
get text 
get value 
hihihihi 

Ответы [ 2 ]

2 голосов
/ 12 мая 2020

Приведенный выше ответ работает, но есть более элегантное решение. Вам не хватает receiver в аргументах Proxy trap и Reflect. Просто измените Proxy на это:

const proxyHandler = {
  get: function(target, prop, receiver) {
    console.log("get", prop);
    return Reflect.get(target, prop, receiver);
  }
};

Обратите внимание на новый receiver в аргументах trap и Reflect.

Между ловушками Proxy есть важное различие target и receiver. В этом случае target - это базовый необработанный объект, а receiver - это оболочка прокси. Если вы не передадите receiver вызову Reflect, все внутри операции get будет запущено против необработанного объекта и не будет запускать ловушки прокси.

Если у вас есть время, я предлагаю вам прочтите соответствующие части ES6 spe c, чтобы полностью понять asp разницу между этими двумя. В противном случае просто убедитесь, что вы перенаправляете все аргументы ловушки прокси в соответствующий вызов Reflect, если вы стремитесь к прозрачному переносу.

1 голос
/ 11 мая 2020

Вы можете установить для экземпляра Proxy объект proxyHandler и получить доступ к свойствам через него (вместо this).

const proxyHandler = {
  get: function(target, prop) {
    console.log("get", prop);
    return Reflect.get(target, prop);
  }
};
const proxifiedObj = {
    value: 4,
    text: "hi",
    get textVal() {
      return this.proxyInstance.text.repeat(this.proxyInstance.value);
    },
    getTextVal() {
      return this.text.repeat(this.value);
    }
}

obj = proxifiedObj.proxyInstance = new Proxy(proxifiedObj, proxyHandler);



console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);    
console.log(obj.textVal);
get getTextVal 
get text 
get value 
hihihihi 

Обновление:

Или вы можете сделать то же самое, создав пользовательский Proxy, который выполняет задание для вас
(Примечание: класс Proxy не может быть расширен, но мы можем использовать возвращаемое значение конструктора шаблон):

  class InstanceAwareProxy {
      constructor(proxifiedObject, proxyHandler) {
          return proxifiedObject.proxyInstance 
                 = new Proxy(proxifiedObject, proxyHandler);
      }
  }

  obj = new InstanceAwareProxy(proxifiedObj, proxyHandler);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...