New

new 操作符在 JavaScript 中用于创建一个由构造函数定义的对象实例。它的内部具体执行过程可以分为以下几步:


new 的执行过程

假设我们有如下构造函数:

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

执行 const person = new Person('Alice'); 时,new 操作符具体执行了以下步骤:


1. 创建一个空对象

  • 创建一个新对象,称为 obj
  • 这个对象的内部 [[Prototype]] 指针会被设置为构造函数的 prototype 属性。
let obj = {}; // 创建一个空对象
obj.__proto__ = Person.prototype; // 设置原型链

2. 绑定 this

  • 将新创建的对象 obj 绑定到构造函数的 this 上,并执行构造函数代码。
let result = Person.call(obj, 'Alice'); // 将 `this` 指向 `obj`,并传入参数

3. 返回对象

  • 如果构造函数返回了一个非原始类型的对象(如对象或数组),则返回该对象。
  • 如果构造函数返回的是一个原始值(如字符串、数字、布尔值),或者没有显式返回值,则返回新创建的对象 obj
return typeof result === 'object' && result !== null ? result : obj;

完整模拟实现

以下是 new 操作符的一个简化实现:

function myNew(Constructor, ...args) {
  // 1. 创建一个空对象,并将其原型指向构造函数的 prototype
  const obj = Object.create(Constructor.prototype);

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

  // 3. 返回结果
  return typeof result === 'object' && result !== null ? result : obj;
}

使用 myNew 实现 new

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

const person = myNew(Person, 'Alice');
console.log(person.name); // 输出: Alice

new 的作用总结

  1. 创建一个新对象。
  2. 将该对象的原型设置为构造函数的 prototype
  3. 执行构造函数,并将新对象作为 this
  4. 根据构造函数的返回值,决定返回的是显式返回的对象还是新创建的对象。

注意事项

原型链继承:

  • 新对象的 __proto__ 指向构造函数的 prototype
  • 这使得新对象可以访问构造函数原型上的方法和属性。

返回值影响:

  • 如果构造函数显式返回一个对象,new 操作符会忽略新创建的对象,返回该对象。
  • 如果返回的是原始值,new 仍会返回新创建的对象。

构造函数的调用:

  • 构造函数是普通函数,但如果不使用 new 调用,this 将指向全局对象(在严格模式下为 undefined),导致逻辑错误。

苏ICP备2025153828号