JavaScript 构造函数返回对象字面量时会创建几个对象?
数据小许
结论
按 JavaScript 的构造语义,基类构造函数执行时会先初始化 this,随后创建并返回对象字面量 {}。语义上涉及两个对象:x 引用返回的空对象,this 对象没有被返回。
ECMAScript 规定程序可观察到的行为,但不要求引擎为每个对象都实际分配堆内存。引擎可以省去不会影响可观察行为的分配,因此无法保证运行时一定分配了两个对象。
这段代码的执行过程
class MyClass {
constructor() {
return {};
}
}
const x = new MyClass();
MyClass 是基类。调用 new MyClass() 时,构造函数体执行前会初始化 this。执行 return {} 时,会创建一个对象字面量。基类构造函数显式返回对象后,new 表达式的结果就是这个对象,而非原先的 this。
按语义步骤,可以这样理解:
- 为构造函数的
this创建实例对象。 - 执行
{},创建另一个对象。 - 返回第二个对象,并赋给
x。 - 如果第一个对象没有其他引用,它就会变得不可达,之后可由垃圾回收器回收。
实际分配取决于引擎优化
语义上创建对象,与引擎实际在堆上分配内存,是两回事。JavaScript 引擎可以在不改变程序可观察结果的前提下消除不必要的分配。对于这个简单示例,某个引擎可能不会实际分配未被使用的 this 对象,也可能进行其他优化。代码无法保证具体会采用哪种优化,也无法确定对象何时回收。
因此,按对象创建的语义过程来回答,涉及两个对象;若问某次运行中的物理内存分配次数,则没有适用于所有引擎和优化级别的固定答案。
注意事项
这里讨论的是基类构造函数。派生类构造函数初始化 this 的规则不同:必须先调用 super(),返回对象的行为也受派生类构造规则约束,因此不能直接套用上述执行顺序。
备注:内容仅供参考。
