You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Proxy捕获子类继承代理父类时添加方法的操作?

解决思路

首先要明确:你当前的代码无法监控到子类B添加自身方法hello的操作,原因是子类的方法是直接添加到B.prototype上的,而不是父类A或A.prototype。你给A设置的Proxy只能拦截对A自身(比如静态属性)或A.prototype的属性修改,和子类自身的prototype无关。

下面分两种场景给出解决方案:

场景1:监控子类修改父类原型的操作

如果你的需求是监控子类对父类A原型的修改(比如子类往父类原型上添加方法),当前的Proxy配置已经可以实现,只需要调整子类的写法:

class A {}

const handler = {
  get(target, property) {
    console.log("getting", property);
    return target[property];
  },
  set(target, property, value) {
    console.log(`setting ${property}`);
    target[property] = value;
    return true;
  },
};

const A_proxied = new Proxy(A, handler);

// 子类修改父类原型时会触发set拦截
class B extends A_proxied {
  constructor() {
    super();
    // 往父类原型添加方法,会输出"setting hello"
    A_proxied.prototype.hello = () => "world";
  }
}

new B();

场景2:监控子类添加自身方法的操作

如果需要监控子类自身prototype上的方法添加,你需要代理子类的prototype。可以通过以下两种方式实现:

方式1:手动代理子类prototype

直接在子类定义后,将其prototype替换为Proxy对象:

class A {}

class B extends A {
  hello() {
    return "world";
  }
}

// 代理B的prototype,监控属性设置
B.prototype = new Proxy(B.prototype, {
  set(target, property, value) {
    console.log(`setting ${property}`);
    target[property] = value;
    return true;
  }
});

// 后续添加方法会触发监控
B.prototype.foo = () => "bar"; // 输出"setting foo"

方式2:自动代理子类(工具函数封装)

如果你希望子类继承父类时自动开启监控,可以封装一个工具函数来创建子类:

class A {}

// 封装工具函数,自动代理子类的prototype
function createMonitoredChild(Parent, classDef) {
  // 创建子类
  const Child = class extends Parent {
    ...classDef
  };
  // 代理子类prototype
  Child.prototype = new Proxy(Child.prototype, {
    set(target, property, value) {
      console.log(`setting ${property}`);
      target[property] = value;
      return true;
    }
  });
  return Child;
}

// 使用工具函数创建子类
const B = createMonitoredChild(A, {
  hello() {
    return "world";
  }
});

// 输出"setting hello"
new B();

内容的提问来源于stack exchange,提问作者vixalien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:14:52