new 的核心是让构造函数的 this 指向新创建的空对象并正确继承其原型;三步为:创建关联原型的空对象、以该对象为 this 调用构造函数、按返回值类型决定最终结果。

手动模拟 new 的核心,是让构造函数内部的 this 指向一个**新创建的空对象**,且该对象能正确继承构造函数的原型。
new 的执行逻辑(关键三步)
JavaScript 中 new Foo() 实际做了三件事:
- 创建一个空对象,其
[[Prototype]]指向Foo.prototype - 以这个新对象为
this,调用Foo构造函数(即Foo.call(newObj, ...args)) - 若构造函数显式返回一个对象,则返回它;否则返回上一步创建的新对象
手动实现 new 的常见写法
下面是一个简洁可靠的模拟:
function myNew(constructor, ...args) {
// 1. 创建空对象,关联原型
const obj = Object.create(constructor.prototype);
// 2. 绑定 this 并执行构造函数
const result = constructor.apply(obj, args);
// 3. 判断返回值:优先返回对象类型结果
return (result !== null && typeof result === 'object') ? result : obj;
}
这里 this 的指向完全由 constructor.apply(obj, args) 控制——obj 就是构造函数体内 this 的值。
为什么不能直接用 {} 或 new Object()?
{} 或 new Object() 创建的对象,其原型是 Object.prototype,而非构造函数的 prototype。必须用 Object.create(Foo.prototype) 才能保证原型链正确,后续实例才能访问到 Foo.prototype 上的方法和属性。
构造函数返回值对 this 的影响
this 的指向在 apply 那一刻就已确定,不会因返回值改变。但最终返回谁,会影响外部拿到的结果:
- 构造函数返回
{}、[]、new Date()等对象 → 外部得到该对象(this仍指向原实例,只是被丢弃) - 返回
undefined、null、字符串、数字等原始值 → 外部得到新创建的实例对象(即this所指对象)
这也是模拟中第三步判断返回值类型的依据。

















