How to use a Proxy in javascript to capture a constructor while maintaining the prototype chain?

杀马特。学长 韩版系。学妹 提交于 2019-12-11 20:08:40

问题


I want to create a constructor object whose inheritance works as normal, but capture the constructor so I can manipulate the instance object. Using Proxy() almost solves this, but it seems to screw up the inheritance. Note the following example without a proxy:

> const B = function() {}
undefined
> B.name
'B'
> class C extends B {}
[Function: C]
> B.prototype == C.prototype.__proto__
true
> var instance = new C()
undefined
> C.prototype == instance.__proto__
true
> instance.__proto__
C {}

Now, if I add a proxy to capture construct(target,args), it will correctly capture the constructor, but it doesn't preserve things exactly as it would without the proxy. Note that all the constructor does is print a message to the console noting its capture. But otherwise (I think) it should react the same. However, when I create a class to extend the proxied function, it seems like the extended function is missing entirely. Note the last four lines give different results than above.

> const handler = { construct(target,args) {
... console.log('Captured!'); return new target(...args); } }
undefined
> const proxy_B = new Proxy(B, handler)
undefined
> proxy_B.name
'B'
> class C2 extends proxy_B {}
[Function: C2]
> proxy_B.prototype == C2.prototype.__proto__
true
> var instance2 = new C2()
Captured!
undefined
> C2.prototype == instance2.__proto__
false
> instance2.__proto__
B {}

What am I doing wrong? How do I write the proxy to properly handle this case?


回答1:


Your handler doesn't handle the new.target. Notice that the target of your proxy is B, and when you return new target then you'll construct a B instance not a C instance.

Instead of approximating the construction behaviour with new, use the Reflect object (in particular Reflect.construct) to use the exact default construction behaviour and pass all the arguments of the trap method:

const handler = {
    construct(target, args, newtarget) {
//                          ^^^^^^^^^
        console.log('Captured!');
        return Reflect.construct(target, args, newtarget);
//                                             ^^^^^^^^^
    }
};


来源:https://stackoverflow.com/questions/49738211/how-to-use-a-proxy-in-javascript-to-capture-a-constructor-while-maintaining-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!