У меня есть следующий надуманный код:
class Animal {
get age() {
return this.baseage + 10;
}
age2() {
return this.baseage + 10;
}
}
const handler = {
"get": function(target, key) {
if (key === "baseage") {
return 20;
}
return target[key];
}
};
const animal = new Proxy(new Animal(), handler);
console.log(animal.age);
console.log(animal.age2());
Что производит
NaN
30
На узле 6.11.0.
Я бы ожидал, что код в классе getter, особенно this.baseage
, this.baseage
пройдет через обработчик прокси, но это, похоже, не так. Есть ли причина для этого?
return target[key];
это не то же поведение, что и обработчик get
по умолчанию. Это является причиной нарушения функции get age
.
const handler = {
"get": function(target, key) {
if (key === "baseage") {
return 20;
}
return target[key];
}
};
должно быть
const handler = {
"get": function(target, key, receiver) {
if (key === "baseage") {
return 20;
}
return Reflect.get(target, key, receiver);
}
};
Когда вы target[key]
вы вызываете get age(){
, но вы вызываете его с target
как this
, это new Animal
объект new Animal
, а не прокси. Поскольку объект Proxy - это тот, который обрабатывает baseage
, а не Animal
, вы возвращаетесь в undefined
.
В этом примере receiver
является фактическим прокси-объектом, поэтому вы можете потенциально сделать receiver[key]
для работы вашего фрагмента, но есть еще много случаев с краями, которые вы все равно не будете обрабатывать в общем виде.
Каждая функция Proxy
обработчика имеет версию Reflect.XX
которая предоставляет поведение по умолчанию. Всякий раз, когда вы пишете прокси-сервер и хотите, чтобы он действовал так, как обычно, вы должны использовать Reflect
.