2、✅ 彻底搞懂 new 操作符的手写实现

55 阅读1分钟

🎯 一、为什么要手写 new

面试中经常问:

  • "new 关键字到底做了什么?"
  • "你能用代码模拟 new 的行为吗?"

理解 new 的本质,你才能真正理解:

  • 构造函数的运行机制
  • this 指向规则
  • 原型继承关系

🔍 二、面试官考察的重点

  • 能否用代码一步步“还原”new 的内部逻辑
  • 是否理解构造函数实例对象的原型绑定
  • 能否识别 return 值是对象时的特殊逻辑

🧠 三、new 做了哪些事?

const obj = new Foo(arg1, arg2);

等价于:

  1. 创建一个空对象 obj
  2. 将该对象的 __proto__ 指向 Foo.prototype
  3. this 绑定为该对象并执行 Foo 函数
  4. 如果构造函数 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
                                └──────────────────┘