返回

JS 中 new 一个函数,究竟发生了什么?

前端

在 JavaScript 中,new 运算符是一个强大的工具,它允许我们创建自定义对象并通过构造函数对其进行初始化。当我们使用 new 调用一个函数时,它背后会发生一系列复杂的步骤,涉及到构造函数、原型和原型链。

构造函数

构造函数是一个特殊的函数,其名称大写。它的主要作用是创建并初始化新对象。当我们通过 new 关键字调用一个函数时,该函数会自动作为构造函数执行。

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

const person1 = new Person("John");
console.log(person1.name); // 输出: John

在上面的示例中,Person 是一个构造函数。当我们使用 new 关键字调用它时,会创建一个名为 person1 的新对象,并使用 name 参数对其进行初始化。

原型

每个 JavaScript 函数都有一个称为原型的属性。原型是一个对象,它包含与该函数相关联的方法和属性。当我们使用 new 关键字调用一个函数时,会创建一个新对象,其原型指向构造函数的原型。

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

Person.prototype.greet = function() {
  console.log("Hello, my name is " + this.name);
};

const person1 = new Person();
person1.greet(); // 输出: Hello, my name is Unknown

在上面的示例中,Person 函数的原型包含一个名为 greet 的方法。当我们使用 new 关键字调用 Person 函数时,会创建一个新对象 person1,其原型指向 Person 函数的原型。因此,person1 对象可以访问 greet 方法,尽管它在 person1 对象本身中没有定义。

原型链

JavaScript 中的每个对象都有一个指向其原型的内部链接,称为原型链。当一个对象尝试访问一个不存在的属性或方法时,它会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末尾(null)。

const person1 = new Person();
console.log(person1.hasOwnProperty("name")); // 输出: true
console.log(person1.hasOwnProperty("greet")); // 输出: false

在上面的示例中,person1 对象没有自己的 greet 属性,但它可以访问 greet 方法,因为它的原型 (Person.prototype) 具有该方法。这是因为 JavaScript 会沿着原型链向上查找 greet 属性,直到在 Person.prototype 中找到它。

总结

当我们使用 new 关键字调用一个函数时,背后会发生以下步骤:

  1. 创建一个新对象。
  2. 设置新对象的原型指向构造函数的原型。
  3. 执行构造函数,并使用传递的参数对新对象进行初始化。

了解 new 运算符的工作原理对于在 JavaScript 中创建和使用自定义对象至关重要。它使我们能够创建具有独特属性和行为的对象,从而构建复杂且可重用的代码。