Menu Close

JavaScript 构造函数

在本教程中,您将学习 JavaScript 构造函数以及如何使用 new 关键字创建对象。

一、JavaScript 构造函数简介

什么是构造函数?

构造函数(Constructor Function)是用来创建多个相似对象的函数。通过 new 关键字调用时,它会返回一个新的对象,并自动设置好 this 和原型。

构造函数的定义语法

构造函数的命名通常首字母大写,以示区别。

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    console.log("Hi, I'm " + this.name);
  };
}

JavaScript 对象教程中,您学习了如何使用对象字面量语法创建新对象。

例如,以下代码创建了一个具有两个属性 firstNamelastName 的新 person 对象:

let person = {
    firstName: 'John',
    lastName: 'Doe'
};

在实际应用中,您经常需要创建许多类似于 person 对象的对象。

为此,您可以使用构造函数定义自定义类型,并使用 new 运算符从该类型创建多个对象。

从技术上讲,构造函数是具有以下约定的常规函数:

  • 构造函数的名称以大写字母开头,如 PersonDocument 等。
  • 构造函数应仅使用 new 运算符调用。

使用构造函数创建对象

使用 new 关键字调用构造函数:

let p1 = new Person("Alice", 25);
let p2 = new Person("Bob", 30);

p1.sayHello(); // 输出: Hi, I'm Alice
p2.sayHello(); // 输出: Hi, I'm Bob

请注意,ES6 引入了 class 关键字,允许您定义自定义类型。类只是构造函数的一种语法糖,并带有一些增强功能。

以下示例定义了一个名为 Person 的构造函数:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

在此示例中,Person 与常规函数相同,只是其名称以大写字母 P 开头。

要创建 Person 的新实例,您使用 new 运算符

let person = new Person('John','Doe');

基本上,new 运算符执行以下操作:

  • 创建一个新的空对象,并将其分配给 this 变量。
  • 将参数 'John''Doe' 分配给对象的 firstNamelastName 属性。
  • 返回 this 值。

它在功能上等同于以下内容:

function Person(firstName, lastName) {
    // this = {};

    // 向 this 添加属性
    this.firstName = firstName;
    this.lastName = lastName;

    // return this;
}

因此,以下语句:

let person = new Person('John','Doe');

… 返回的结果与以下语句相同:

let person = {
    firstName: 'John',
    lastName: 'Doe'
};

然而,构造函数 Person 允许您创建多个类似的对象。例如:

let person1 = new Person('Jane','Doe');
let person2 = new Person('James','Smith');

二、向 JavaScript 构造函数添加方法

对象可能具有操作其数据的方法。要向通过构造函数创建的对象添加方法,您可以使用 this 关键字。例如:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    this.getFullName = function () {
        return this.firstName + " " + this.lastName;
    };
}

现在,您可以创建一个新的 Person 对象并调用 getFullName() 方法:

let person = new Person("John", "Doe");
console.log(person.getFullName());

输出:

John Doe

构造函数的问题在于,当您创建 Person 的多个实例时,this.getFullName() 在每个实例中都会被复制,这在内存使用上效率不高。

为了解决这个问题,您可以使用原型,以便所有自定义类型的实例共享相同的方法。

三、构造函数的返回值

通常,构造函数隐式返回设置为新创建对象的 this。但如果它有一个 return 语句,则遵循以下规则:

  • 如果 return 返回一个对象,构造函数返回该对象而不是 this
  • 如果 return 返回的不是对象的值,则会被忽略。

四、不使用 new 关键字调用构造函数

从技术上讲,您可以像常规函数一样调用构造函数,而不使用 new 关键字,如下所示:

let person = Person('John','Doe');

在这种情况下,Person 只是像常规函数一样执行。因此,Person 函数内部的 this 不绑定到 person 变量,而是绑定到全局对象。

为了防止构造函数在没有 new 关键字的情况下被调用,ES6 引入了 new.target 属性。

READ  JavaScript switch 语句

如果使用 new 关键字调用构造函数,new.target 返回对该函数的引用。否则,它返回 undefined

以下代码在 Person 函数中添加了一条语句,将 new.target 显示在控制台中:

function Person(firstName, lastName) {
    console.log(new.target);
    this.firstName = firstName;
    this.lastName = lastName;
}

然而,以下代码由于使用了 new 关键字,因此返回对 Person 函数的引用:

let person = new Person("John", "Doe");

输出:

[Function: Person]

通过使用 new.target,您可以强制构造函数的调用者使用 new 关键字。否则,您可以抛出错误,如下所示:

function Person(firstName, lastName) {
    if (!new.target) {
        throw Error("Cannot be called without the new keyword");
    }

    this.firstName = firstName;
    this.lastName = lastName;
}

或者,您可以使语法更灵活,如果构造函数的用户没有使用 new 关键字,则创建一个新的 Person 对象。

五、总结

  • JavaScript 构造函数是用于创建多个相似对象的常规函数。

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!
Posted in 对象与原型

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!