代理ES6类并维护原型链

Tim*_*Tim 4 javascript proxy ecmascript-6

我使用以下包装器代理方法:

  public static wrap(target) {
    function construct(constructor, args) {
      const c: any = function(this) {
        return constructor.apply(this, args);
      };

      c.prototype = constructor.prototype;
      return new c();
    }

    const f = (...args) => {
      const instance = construct(target, args);

      const descriptors = getMethodDescriptors(target, instance);

      return new Proxy<T>(
        instance,
        new SomeProxyHandler(descriptors)
      );
    };

    f.prototype = target.prototype;
    return f;
  }
Run Code Online (Sandbox Code Playgroud)

这在包装编译到ES5的类时运行良好但是现在我试图以ES6为目标我在constructor.apply(this, args)说:

TypeError: Class constructor OneOfMyClasses cannot be invoked without 'new'
Run Code Online (Sandbox Code Playgroud)

如何修复此代码,以便wrap代理任何JavaScript目标的类并维护正确的原型链?

Ber*_*rgi 5

最简单的方法是传播语法

const instance = new target(...args);
Run Code Online (Sandbox Code Playgroud)

但你也可以使用Reflect.construct:

const instance = Reflect.construct(target, args);
Run Code Online (Sandbox Code Playgroud)

如果您的包装类应该是可扩展的,那么这甚至是必要的,然后您将不得不使用new.target:

const instance = Reflect.construct(target, args, new.target);
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你的f包装器应该是一个正确的function而不是箭头功能,因为那些不能被调用new(并且没有new.target).或者甚至可能更简单(使用静态方法和继承更好地工作),只需将整个target类本身包装在一个Proxy并使用它的construct陷阱.