构造函数返回引用类型会覆盖new结果,丢弃原实例并导致原型链断裂、instanceof失效;返回原始值则被忽略,仍返回标准实例;不返回或返回undefined才是正确行为。

构造函数的返回值会直接干预 new 表达式的最终结果,不是“补充行为”,而是“覆盖行为”——它可能让本该生成的实例彻底消失,换成另一个对象。
返回引用类型(对象、数组、函数等):原实例被丢弃
只要构造函数显式 return 一个引用值,new 就立即放弃刚创建的那个空对象和后续绑定的原型链,直接把 return 的值作为整个表达式的结果。
-
__proto__ 断裂:返回对象的
__proto__不指向构造函数的prototype,无法访问原型方法 -
instanceof 失效:比如
obj instanceof MyClass返回false -
constructor 属性丢失或错乱:返回对象的
constructor通常指向Object,而非原构造函数 - 继承链中断:子类构造函数中这么做,父类初始化虽已执行,但最终对象既不是子类实例,也不是父类实例
返回原始值(string、number、boolean、null、undefined):返回值被忽略
此时 new 完全无视 return,照常返回初始化完成的新实例。
- 即使写
return 42或return "hello",结果仍是带this.xxx属性的标准实例 -
return undefined和没写return效果一致(JS 函数默认返回undefined) - 这种情况下,实例的原型链、
instanceof、constructor全部正常
不 return 或 return undefined:最标准的行为
这是构造函数的预期用法。引擎自动返回新创建并初始化完毕的 this 对象。
- 原型链正确建立:
实例.__proto__ === 构造函数.prototype - 所有基于原型的方法和属性可正常继承与调用
- 符合面向对象语义,支持安全的继承、多态和类型检测
常见误用场景提醒
很多看似“合理”的写法,其实悄悄破坏了构造机制:
- 在 class 构造器里
return { ... }—— 子类实例化失败,super()的效果白费 - 把工厂函数包装成“构造函数”,靠
return new SomeClass()混淆类型 —— 实际绕过了new流程和继承链 - 构造函数内部根据条件返回不同对象(如缓存对象或单例)—— 表面是实例,实则失去类型身份和扩展能力











