如何让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
相关产品推荐
相关产品推荐

