模拟JS中new关键字的执行

193 阅读1分钟

在 JavaScript 中,new 关键字用于创建一个用户定义的对象实例。具体执行步骤如下:


new 关键字的执行步骤

  1. 创建新对象:创建一个空的普通对象 {},并将其原型([[Prototype]])指向构造函数的 prototype 属性。

  2. 绑定 this 上下文:将构造函数内部的 this 绑定到新创建的对象。

  3. 执行构造函数:执行构造函数内部的代码(通常用于初始化对象属性)。

  4. 处理返回值

    • 如果构造函数返回一个对象,则返回该对象。
    • 如果构造函数返回原始值(如 undefined、数字、字符串等),则忽略返回值,返回新创建的对象。

模拟 new 关键字的伪代码实现

function new2(Constructor, ...args) {
  // 1. 创建一个新对象,并链接到构造函数的原型
  const obj = Object.create(Constructor.prototype);

  // 2. 调用构造函数,绑定 this 到新对象
  const result = Constructor.apply(obj, args);

  // 3. 处理返回值:如果是对象则返回,否则返回新对象
  return result instanceof Object ? result : obj;
}

代码示例

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}`);
};

// 使用原生 new
const alice = new Person("Alice");
alice.sayHello(); // 输出: Hello, I'm Alice

// 使用模拟的 new2
const bob = new2(Person, "Bob");
bob.sayHello(); // 输出: Hello, I'm Bob

关键细节

  1. 原型链链接:通过 Object.create(Constructor.prototype) 确保新对象的原型正确。
  2. 构造函数调用:使用 apply 将构造函数的作用域绑定到新对象。
  3. 返回值处理:优先返回构造函数显式返回的对象,否则返回新对象。

边界情况验证

  1. 构造函数返回对象

    function Dog() {
      return { bark: "Woof!" };
    }
    const dog = new2(Dog);
    console.log(dog.bark); // 输出: Woof!
    
  2. 构造函数返回原始值

    function Cat() {
      return "Meow";
    }
    const cat = new2(Cat);
    console.log(cat); // 输出: Cat {}(忽略返回值)