前端面试题-new关键字实现原理

156 阅读2分钟

定义

在JavaScript中,new 关键字用于创建一个用户自定义的对象类型的实例或具有构造函数的内置对象的实例。当使用 new 关键字调用一个函数时,JavaScript引擎会执行以下步骤来创建并初始化一个新对象:

  1. 创建一个新的空对象:首先,JavaScript会创建一个新的空对象。这个对象就是将来要被返回的对象实例。
  2. 设置原型链:新创建的对象的内部链接([[Prototype]])被设置为构造函数的prototype对象。这意味着新创建的对象会继承构造函数原型上的属性和方法。
  3. 绑定this上下文:函数内部的this关键字被绑定到新创建的对象上。这意味着在构造函数内部,你可以通过this关键字来访问和修改新对象的属性。
  4. 执行构造函数:构造函数被调用,其代码被执行。在这个过程中,this 指向新创建的对象,因此任何通过 this 添加的属性或方法都会成为新对象的一部分。
  5. 判断返回值:如果构造函数返回一个非原始值(即一个对象或函数),那么这个返回值会被用作 new 表达式的结果。否则,新创建的对象会被用作结果。通常,构造函数不应该返回非原始值,除非你有特定的理由这么做。
  6. 返回新对象:最终,new 表达式返回新创建的对象。

实现步骤

function new_(constructor, ...args) {
  // 步骤 1:创建一个空的对象, 将空对象的原型指向构造函数的原型
  const obj = Object.create(constructor.prototype);
  // 步骤 2:调用构造函数并修改this指向
  const nObj = constructor.apply(obj, args);
  // 步骤 3:如果构造函数又返回对象则使用构造函数返回的对象
  if (typeof nObj === "object" && nObj !== null) {
    return nObj;
  }
  // 步骤 4:如果 3 不成立, 则返回新创建的对象
  return obj;
}

// 使用
function Person(name, age) {
  this.name = name;
  this.age = age;
}

var val = new_(Person, "lee", 23);
console.log(val); // { name: 'lee', age: 23 }