🎯 一、为什么要手写 new?
面试中经常问:
- "
new关键字到底做了什么?" - "你能用代码模拟
new的行为吗?"
理解 new 的本质,你才能真正理解:
- 构造函数的运行机制
- this 指向规则
- 原型继承关系
🔍 二、面试官考察的重点
- 能否用代码一步步“还原”new 的内部逻辑
- 是否理解构造函数实例对象的原型绑定
- 能否识别 return 值是对象时的特殊逻辑
🧠 三、new 做了哪些事?
const obj = new Foo(arg1, arg2);
等价于:
- 创建一个空对象
obj - 将该对象的
__proto__指向Foo.prototype - 将
this绑定为该对象并执行Foo函数 - 如果构造函数
return一个对象类型,则new表达式的结果就是这个对象,否则返回步骤 1 创建的对象
✍️ 四、手写 new
function myNew(Constructor, ...args) {
// 1. 创建一个空对象,设置原型指向构造函数的 prototype
const obj = Object.create(Constructor.prototype);
// 2. 执行构造函数,将 this 指向这个新对象
const result = Constructor.apply(obj, args);
// 3. 返回结果:如果构造函数返回的是对象,则返回该对象,否则返回 obj
return (typeof result === 'object' && result !== null) || typeof result === 'function'
? result
: obj;
}
✅ 五、用例验证
function Person(name, age) {
this.name = name;
this.age = age;
}
const p = myNew(Person, '小明', 18);
console.log(p.name); // 小明
console.log(p.__proto__ === Person.prototype); // true
✅ 特殊情况验证
function Animal() {
return { type: 'cat' };
}
const a = myNew(Animal);
console.log(a.type); // cat
❗ 六、常见易错点与考法
| 错误点 | 正确处理 |
|---|---|
| 忘记绑定原型 | Object.create(Constructor.prototype) |
| 忘记处理返回对象的情况 | 判断 return 是否为对象/函数 |
Object.setPrototypeOf | 不建议直接用,面试常让用 Object.create |
📘 七、扩展问题
- 如果
Constructor.prototype = null怎么办? - 如果构造函数是箭头函数呢?(箭头函数没有 prototype,不可 new)
🎁 八、补充理解图示
┌────────────┐
│ Constructor│
└─────┬──────┘
↓
┌───────────────┐
│ Constructor.prototype ────────────┐
└──────────────────────────────────┘
↓
┌──────────────────┐
│ obj │
│ __proto__ → Constructor.prototype
└──────────────────┘