如何修改ES6类的构造函数

时间:2019-03-18 21:20:37

标签: javascript ecmascript-6 es6-class

我正在尝试使用ES6类重新加载热代码。我需要能够修改类的构造函数,而不必用新的类替换该类(因为其他人可能会引用它)。

但是,我发现类对象似乎对最初定义的构造函数有一些内部引用;用new实例化类不会在类上查找constructorprototype.constructor

示例:

class OldC { constructor() { console.log("old"); } }
class NewC { constructor() { console.log("new"); } }

OldC.prototype.constructor = NewC.prototype.constructor;
OldC.constructor = NewC.constructor;
new OldC();

--->“旧”

(更新所有其他方法都很好;这只是我遇到麻烦的构造方法。)

考虑到可以通过[[prototype]]找到构造函数,我还添加了以下内容:

Object.setPrototypeOf(OldC, Object.getPrototypeOf(NewC));
Object.setPrototypeOf(OldC.prototype, Object.getPrototypeOf(NewC.prototype));

这也无济于事(考虑到没有子类的发生,我也不会期望如此)。

所有这些之后,检查OldC显示原型属性完全符合我的期望,其中OldC.prototype.constructor是新属性。但是,构造OldC实例仍会调用原始构造函数。

这是怎么回事,我该如何解决?

1 个答案:

答案 0 :(得分:1)

  

仍然,构造OldC的实例将调用原始构造函数。

是的,因为OldC本身是构造函数。您需要覆盖OldC变量以更改new OldC的作用。

  

修改类的构造函数,而不用新的类替换该类(因为其他人可能会引用它)。

正如@trincot在评论中指出的,you cannot modify the code of a function。您必须用新的构造函数替换构造函数,无法解决。

尽管如此,您仍可以保留原型对象(这是可变的),因为这是大多数其他事物(尤其是旧实例)将引用的对象。

NewC.prototype = OldC.prototype;
NewC.prototype.constructor = NewC;
OldC = NewC;

引用旧的构造函数且现在无法更改的人们将无济于事。最好的选择是根本不分发类本身,而只是分发更新代码可以修改其行为的工厂。