ES6类constructor总是返回新创建的实例对象,显式返回非null对象会抛TypeError;new调用时先创建空对象并绑定this,子类必须先调用super();为保持原型链和instanceof语义,禁止return自定义对象,特殊需求应使用工厂函数。

ES6 类中 constructor 的返回值不会改变 new 表达式的结果,除非显式返回一个非 null 对象——但这种情况在 class 中直接报错,所以实际运行中 constructor 总是返回新创建的实例对象。
class 构造器禁止返回自定义对象
与 function 构造函数不同,ES6 class 的 constructor 方法不允许显式返回非 this 对象。一旦写成 return {x: 1} 或 return [],JavaScript 引擎会在运行时抛出 TypeError。这是语言规范强制设定的行为,目的是保障类实例的语义一致性:每个 new Class() 都必须是一个该类的合法实例。
- 即使 return this,也等同于不写 return,结果不变
- return undefined、null、42、"ok" 等原始值,全部被忽略,仍返回新实例
- return 一个对象字面量(如 {}、/reg/、new Date())会立即中断执行并报错
constructor 执行流程与 this 绑定
new 调用 class 时,引擎内部按固定步骤执行:先分配空对象,设置其 __proto__ 指向 Class.prototype,再将 this 绑定到该对象,最后执行 constructor 函数体。这个过程不可跳过或替换。
- 子类 constructor 必须先调用 super(),否则访问 this 会报 ReferenceError
- super() 实质是调用父类构造函数,并把当前子类实例的 this 传进去加工
- constructor 中对 this 的赋值(如 this.name = name)最终都落在新实例上
为什么不能靠 return 改变实例?
class 设计初衷是提供清晰、可预测的面向对象模型。若允许任意对象覆盖实例,会导致原型链断裂、instanceof 失效、方法继承丢失等问题。例如:
立即学习“Java免费学习笔记(深入)”;
- 如果 new Person() 返回一个普通对象 {},它就不再有 Person.prototype 上的方法
- obj instanceof Person 变为 false,破坏类型判断逻辑
- 继承链中父类初始化逻辑(如 super() 内部的属性设置)可能被跳过
想实现类似效果?用工厂函数代替
需要返回代理、单例、包装对象等特殊值时,class 不适合直接承担该职责。推荐使用普通函数封装 new 操作:
- 写一个 createPerson(name) 工厂函数,在内部 new Person,再返回包装后的对象
- 用 Proxy 包裹实例,控制访问行为
- 通过静态方法(如 Person.fromData())集中管理构造逻辑
这样既保持类本身的纯净性,又满足灵活构造需求。


















