JavaScript 是一种多范式语言,允许您编写遵循函数式、面向对象和命令式编程风格的程序。
为了支持面向对象的模式,JavaScript 具有类。 因为理解它们至关重要,所以本文是关于 JavaScript 类是什么以及如何使用它们的指南。
目录
JavaScript 中的类是什么?
在面向对象编程中,我们将系统建模为相互交互的对象组。 为了发挥作用,对象将数据存储在属性中并执行定义为其方法的操作。 类定义相同类型的对象携带哪些属性和方法。 因此,类是对象的蓝图。
课堂中使用的术语
为了确保我们意见一致,这里是对类的描述,其中包含我们将在本文中使用的关键术语。 如果您已经熟悉面向对象编程,可以跳到下一节。
❇️ 类是对象的蓝图。 它提供了一个模板,可以根据该模板来制作该类型的对象。 从类提供的模板创建对象称为实例化。
❇️ 班级成员是属于班级的任何东西。 类成员有两种——方法和属性。
❇️ 属性是一个类成员,其主要目的是存储值。 这些可以是简单的值,例如数字和字符串。 它们也可以是复杂的对象和数组。
❇️ 有些属性只能在类内部访问,因此被恰当地命名为私有属性。 有些在课堂内外都可以访问。 此类属性称为公共属性。
❇️ 方法是在类内部定义的函数。 因此,它属于该类,并且可以访问公共和私有属性。 与属性一样,我们也有公共方法和私有方法。
❇️ 存在一些方法来为类外部的代码提供与类内部的属性交互的接口。 有两组方法可以执行此操作:getter 和 setter。 Getter 获取类属性的值,而 Setter 设置类属性的值。
❇️ 有些成员是静态的。 这意味着它们只能在类上访问,而不能在类实例上访问。
相反,某些类成员不是静态的,这意味着它们只能在类实例上访问。 您必须先实例化该类,然后才能访问非静态成员。
当实例化一个类时,会调用一个特殊的方法来设置实例的属性。 该方法称为构造函数。
实例化类解释
我们使用 new 关键字和类名在 JavaScript 中实例化一个类。 例如,让我们实例化 Array 类。
const myArr = new Array()
在 JavaScript 中创建类
本节将讨论创建一个类来实现我们在 术语部分。 我们将通过一系列示例来实现这一点,其中每个示例都建立在前面的示例之上。
声明一个空类
要在 JavaScript 中声明类,我们使用 class 关键字并为类命名。 接下来,我们定义类的主体。 主体用大括号括起来并包含所有类成员。
下面是一个带有空主体的类声明示例:
class Dog { }
现在,您可以按如下方式实例化该类并将其打印出来。
const pet = new Dog; console.log(pet);
创建公共属性
公共属性是用标识符和可选值定义的。
class Dog { name = "Roy"; age; }
在这里,我们定义了带有字符串值的名称和没有值的年龄。
const pet = new Dog(); console.log(pet.name); console.log(pet.age);
定义公共方法
我们可以在类的主体内添加方法。 我们定义方法的方式与定义函数的方式相同。 但是,我们省略了 function 关键字。
class Dog { name = "Roy"; age; walk () { console.log("Walking"); } }
在上面的例子中,我们定义了 walk 方法。 Animal 类的每个实例都有该方法。
const pet = new Dog(); pet.walk();
从方法访问属性
在 JavaScript 中,我们通常使用点运算符访问对象的属性。 例如,如果我们有一个名为 person 的对象并且想要访问 name 属性,我们将按如下方式执行。
person.name
但是,如果我们想从对象内部访问属性,我们可以使用 this 关键字而不是对象名称。 这是一个例子:
this.name
this 关键字引用该对象。 因此,如果我们想从类方法中访问类属性,我们将使用 this.
创建私有财产
假设我们希望之前定义的名称和年龄属性是私有的。 我们将重新定义该类,如下所示:
class Dog { #name = "Roy"; #age; walk () { console.log("Walking"); } }
如您所见,私有属性是使用井号指定的。 如果您尝试访问它们,则会遇到错误。
const dog = new Dog(); dog.#name
创建 Getter 和 Setter 方法
现在,该类的名称和年龄属性是私有的。 因此,它们只能通过类内部的方法访问。
如果我们想让类外部的代码能够访问这些属性,我们可以定义 getter 和 setter。 让我们对 name 属性执行此操作。
class Dog { #name = "Roy"; #age; get name () { return this.#name; } set name (value) { this.#name = value; } walk () { console.log("Walking"); } }
通过上面定义的类,您可以使用以下代码设置名称并显示它:
const pet = new Dog(); // Setting the name pet.name = "Rex"; // Getting the name console.log(pet.name);
创建私有方法
与私有属性一样,私有方法也以井号为前缀。 因此,声明私有方法将如下所示:
class Dog { #name = "Roy"; #age; get name () { return this.#name; } set name (value) { this.#name = value; } #increaseAge() { this.#age ++; } #decreaseAge () { this.#age --; } walk () { console.log("Walking"); } }
如果您尝试从类外部访问这些方法,它将不起作用。
const pet = new Dog(); pet.#increaseAge();
创建构造函数方法
您还可以定义构造函数方法。 每当实例化一个新类时,都会自动调用此方法。 构造函数方法可用于初始化属性。 在此示例中,我们将把年龄和姓名初始化为用户在实例化期间提供的任何参数。
class Dog { #name; #age; constructor (name = "Dog", age = 0) { this.#name = name; this.#age = age; } get name () { return this.#name; } set name (value) { this.#name = value; } #increaseAge() { this.#age ++; } #decreaseAge () { this.#age --; } walk () { console.log("Walking"); } }
当我们实例化我们的类时,我们可以提供姓名和年龄。
const pet = new Dog('Roy', 3); console.log(pet.name);
创建静态属性和方法
如前所述,无需先实例化类即可访问静态成员。 在下面的示例中,我们将创建一个静态属性和方法。
class Dog { #name; #age; static genus = "Canis"; constructor (name = "Dog", age = 0) { this.#name = name; this.#age = age; } static bark() { console.log("Woof"); } get name () { return this.#name; } set name (value) { this.#name = value; } #increaseAge() { this.#age ++; } #decreaseAge () { this.#age --; } walk () { console.log("Walking"); } }
现在,您无需实例化即可访问静态属性和方法。
console.log(Dog.genus); Dog.bark();
遗产
类可以从其他类继承属性。 从另一个类继承成员的类称为超类,而它继承成员的类称为基类或子类。
要在 JavaScript 中创建超类,我们使用 extends 关键字。 这是一个我们继承 Dog 类的示例。
class Rottweiler extends Dog { constructor (name, age) { super(name, age); this.breed = 'rottweiler'; } }
正如您所看到的,课程与以前基本相同。 然而,在构造函数内部,我们调用了 super 函数。 super 关键字引用基类的构造函数。 因此,我们在超类中调用基类的构造函数,并传入姓名和年龄。
const myPet = new Rottweiler(); console.log(myPet);
结论
在本文中,我们介绍了类。 我们介绍了它们是什么、它们可以持有的成员以及成员的不同分类。 然后,我们用例子来说明这一切。
接下来,您可能想阅读面向对象编程面试问题。