new操作符执行四步:创建空对象、绑定Constructor.prototype到其[[Prototype]]、以该对象为this调用构造函数、按返回值类型决定最终返回结果。

JavaScript 中的 new 操作符用于调用构造函数并创建一个新对象。它不是简单地“调用函数”,而是一套有明确顺序的初始化过程:创建空对象、绑定原型、执行构造函数、返回合适的结果。
new 操作符实际做了四件事
当执行 new Constructor(...args) 时,引擎内部会依次完成:
- 创建一个全新的空对象(即
{}) - 将该对象的
[[Prototype]](内部原型)指向Constructor.prototype - 以这个新对象为
this,调用Constructor,并传入参数 - 若构造函数显式返回一个“对象类型”值(非
null的对象、数组、函数、正则等),则返回该值;否则返回新创建的对象
手动实现 new 的核心逻辑
我们可以用普通函数模拟上述行为,关键点在于:正确设置原型、借用构造函数、处理返回值。
以下是一个简洁可靠的实现:
立即学习“Java免费学习笔记(深入)”;
function myNew(Constructor, ...args) {
// 1. 创建空对象
const obj = {};
// 2. 设置原型链:obj.__proto__ = Constructor.prototype
Object.setPrototypeOf(obj, Constructor.prototype);
// 3. 执行构造函数,绑定 this 并传参
const result = Constructor.apply(obj, args);
// 4. 判断返回值:如果是对象或函数,且不为 null,则返回它;否则返回 obj
if (result !== null && (typeof result === 'object' || typeof result === 'function')) {
return result;
}
return obj;
}
为什么不能直接用 obj.__proto__ = ...?
__proto__ 是非标准但广泛支持的属性,但规范推荐使用 Object.setPrototypeOf() 或在创建时用 Object.create(Constructor.prototype)。更健壮的写法可改为:
function myNew(Constructor, ...args) {
const obj = Object.create(Constructor.prototype);
const result = Constructor.apply(obj, args);
if (result != null && (typeof result === 'object' || typeof result === 'function')) {
return result;
}
return obj;
}
这样避免了对 __proto__ 的依赖,也更贴近引擎底层创建对象的方式。
验证实现是否正确
可以这样测试:
function Person(name) {
this.name = name;
}
Person.prototype.say = function() { return 'Hi'; };
const p = myNew(Person, 'Alice');
console.log(p.name); // 'Alice'
console.log(p.say()); // 'Hi'
console.log(p instanceof Person); // true
注意:instanceof 依赖原型链,所以第 2 步设置原型必须准确,否则会失败。











