如何独立执行JavaScript类的构造函数?无需创建新对象实例
解决方案:无需新建对象调用类构造函数初始化已有实例
针对你的需求——用Object.create(A.prototype)创建对象后,调用原类构造函数完成初始化,有两种可行方案:
方案1:修改原类(最简单)
如果能修改原类代码,把构造函数的初始化逻辑抽成独立的实例方法,后续直接调用这个方法即可:
class A { constructor() { this.init(); } init() { console.log("hello"); // 所有初始化逻辑都放到这里 this.name = "test"; } } // 创建未初始化的对象 const a = Object.create(A.prototype); // 直接调用初始化方法 a.init(); console.log(a.name); // 输出test
方案2:不修改原类(适配已有代码)
如果不能改动原类,可借助Proxy和Reflect绕过类构造函数必须用new调用的限制,让构造函数作用在已有对象上:
class A { constructor() { console.log("hello"); this.name = "test"; } } function hydrate(obj) { // 获取对象对应的类构造函数 const Constructor = Object.getPrototypeOf(obj).constructor; // 用Proxy包装构造函数,拦截construct操作 const proxyCtor = new Proxy(Constructor, { construct(target, args) { // 把构造函数的this绑定到已有对象,执行初始化逻辑 Reflect.apply(target, obj, args); // 返回已有对象,替代new默认创建的新对象 return obj; } }); // 用new调用代理构造函数,满足类构造函数对new.target的要求 new proxyCtor(); } // 创建未初始化的对象 const a = Object.create(A.prototype); // 执行初始化 hydrate(a); console.log(a.name); // 输出test
原理说明
类构造函数的限制是:必须通过new或Reflect.construct调用(此时new.target会指向构造函数)。上面的方案用Proxy拦截了new操作,在内部把构造函数的执行上下文绑定到已有对象,同时返回该对象替代默认生成的新实例,既满足了类构造函数的调用要求,又实现了对已有对象的初始化。
内容的提问来源于stack exchange,提问作者vixalien
相关产品推荐
相关产品推荐

