1

JavaScript 构造函数

 1 year ago
source link: https://www.myfreax.com/javascript-constructor-function/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
JavaScript 构造函数

JavaScript 构造函数

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

JavaScript 构造函数简介

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

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

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

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

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

从技术上讲,构造函数是具有以下约定的普通函数​​:

  • 构造函数的名称以大写字母开头 ,例如 Document,  Person 等。
  • 构造函数只能使用 new 运算符创建。
请注意,ES6 引入关键词 class 允许您定义自定义类型。类只是构造函数的语法糖,具有一些增强功能。

以下示例定义了一个构造函数,称为 Person

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

在此示例中,除了其名称以大写字母开头外,Person 与常规函数相同。要创建 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() 在每个实例中都会复制一次,这不是内存高效的用法。

要解决此问题,您可以使用 JavaScript 原型,使自定义类型的所有实例都可以共享相同的方法。

从构造函数返回

通常,构造函数隐式地返回 this。但如果它有一个 return 声明,那么规则如下:

  • 如果return 后面返指定返回的是一个对象,则构造函数返回指定的对象而不是返回 this
  • 如果 return 后面返回不是对象,则会返回默认值 this。

不使用关键词 new 调用构造函数

从技术上讲,您可以像调用普通函数一样调用构造函数,而无需使用像这样使用 new 关键词:

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

在这种情况下,Person 构造函数可以像普通函数一样调用。因此,Person 函数内部的 this 绑定的不是变量 person,而是全局对象

如果您尝试访问person对象的 firstName 或者 lastName 属性,您将收到错误消息 TypeError: Cannot read property 'firstName' of undefined:

console.log(person.firstName);
TypeError: Cannot read property 'firstName' of undefined

同样,您不能访问getFullName()方法,因为它绑定到全局对象。

person.getFullName();
TypeError: Cannot read property 'getFullName' of undefined

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

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

下面在 Person 函数中添加语句 console.log(new.target);  向控制台打印 new.target

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

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

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

以下语句将会打印 undefined,因为 Person 构造函数像普通函数一样被调用:

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

但是,以下语句打印对函数的引用,因为它是使用 new 关键词调用 Person 构造函数:

let person = new Person("John", "Doe");
[Function: Person]

通过使用 new.target,您可以强制构造函数的调用者使用 new 关键词。否则,您可以会抛出这样的错误:

function Person(firstName, lastName) {
    if (!new.target) {
        throw Error("你必须使用 new 关键词调用");
    }

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

或者,如果用户没有使用 new 关键字调用构造函数,您可以自己在构造函数内部调用 Person 构造函数并返回,这使得构造函数更为强壮:

function Person(firstName, lastName) {
    if (!new.target) {
        return new Person(firstName, lastName);
    }

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

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

console.log(person.firstName);

这种模式常用于 JavaScript 库和框架中,使语法更加灵活。

  • JavaScript 构造函数是用于创建多个相似对象的普通函数​​。

微信公众号

支付宝打赏

myfreax 淘宝打赏

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK