简体   繁体   English

如何动态扩展ES5和ES6类

[英]How to dynamically extend ES5 and ES6 classes

I'm trying to build a tool library to be used on every environment. 我正在尝试构建一个可在每种环境下使用的工具库。 I have a transpiler so my generated code is ES5. 我有一个转译器,所以我生成的代码是ES5。

The thing is my tool hooks on a class methods and injects them back in the prototype: 关键是我的工具挂在类方法上,然后将它们重新注入到原型中:

klass.prototype = Object.create(
  Object.getPrototypeOf(klass.prototype),
  modifiedDescriptors
);

But if a ES6 class is passed we can't modify it's prototype because it's descriptor is {configurable: false, writable: false} . 但是,如果通过了ES6类,我们将无法修改它的prototype因为它的描述符是{configurable: false, writable: false} So I decided to fully extend the class with ES5 code and not modify the original prototype: 因此,我决定使用ES5代码完全扩展该类,而不修改原始原型:

function ProxyCtor() { return klass.apply(this, arguments) }
ProxyCtor.prototype = Object.create(klass.prototype, modifiedDescriptors);

Again this is not possible because a ES6 class constructor can't be invoked without new : Class constructor X cannot be invoked without 'new' 同样,这是不可能的,因为没有new不能调用ES6类构造函数: Class constructor X cannot be invoked without 'new'

Ok no problem I'll drop ES5 support and my code will extend the class using ES6 classes and then I will finally be able to hook the methods: 好的,没问题,我将放弃对ES5的支持,我的代码将使用ES6类扩展该类,然后终于可以钩住方法了:

class ProxyCtor extends klass {}

Object.defineProperty(ProxyCtor, 'prototype', Object.create(
  Object.getPrototypeOf(ProxyCtor.prototype),
  modifiedDescriptors
);

And this again fails because ProxyCtor.prototype is readonly as klass.prototype was. 而且这再次失败,因为ProxyCtor.prototype是只读的,就像klass.prototype

I could use Proxy for this but a requirement is to support older browsers and for optimization reasons I need the calculations to be executed on script startup and not when the method is called. 我可以为此使用Proxy ,但是要求是支持较旧的浏览器,并且出于优化的原因,我需要在脚本启动时而不是在调用方法时执行计算。

So the question is... how can I extend a class ES6 (meaning it should have the same behaviour and new ProxyCtor() instanceof klass should be true) but wrap it's methods with a function? 因此,问题是...我如何扩展类ES6(这意味着它应该具有相同的行为,并且new ProxyCtor() instanceof klass应该为true),但是将其方法包装为函数?

Your usage of Object.create to overwrite the .prototype with a new object could as easily be 您可以很容易地使用Object.create来用新对象覆盖.prototype

Object.defineProperties(klass.prototype, modifiedDescriptors)

that keeps the object the same but changes its properties. 使对象保持不变,但更改其属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM