如何在维护原型链的同时在javascript中使用代理来捕获构造函数? [英] How to use a Proxy in javascript to capture a constructor while maintaining the prototype chain?

查看:74
本文介绍了如何在维护原型链的同时在javascript中使用代理来捕获构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个构造函数对象,该继承对象的继承工作正常,但是要捕获该构造函数,以便可以操纵该实例对象。使用 Proxy() 几乎可以解决此问题,但这似乎搞砸了继承。请注意以下没有代理的示例:

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 {}

现在,如果我添加代理来捕获 construct(target,args),它会正确捕获构造函数,但不会像没有代理一样完全保留事物。请注意,构造函数所做的只是向控制台打印一条消息,指出其捕获情况。但是,否则(我认为)它应该做出相同的反应。但是,当我创建一个类来扩展代理功能时,似乎扩展功能完全丢失了。请注意,最后四行给出的结果与上述结果不同。

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 {}

我在做什么错?

推荐答案

您的处理程序无法处理 new.target 。请注意,您代理的目标 B ,并且当您返回新目标,那么您将构造一个 B 实例,而不是一个 C 实例。

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.

不是使用 new 来近似构造行为,而是使用 Reflect 对象(在特定的 Reflect.construct )来使用 exact 默认构造行为并传递trap方法的所有参数:

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);
//                                             ^^^^^^^^^
    }
};

这篇关于如何在维护原型链的同时在javascript中使用代理来捕获构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆