JavaScript 类入门
大家好👋,我将从这篇文章开始,开启一系列关于 JavaScript 概念的文章。因此,我将以一篇关于 JavaScript 类的文章作为本系列的开篇。在本文中,我将涵盖所有关于 JS 类入门的知识。
目录 -
- JS 类的基础知识
- getter 和 setter
- 静态方法
- 继承和扩展
- 多态性
JS 类的基础知识
“在面向对象编程中,类是一个可扩展的程序代码模板,用于创建对象、为状态(成员变量)提供初始值以及提供行为的实现(成员函数或方法)。” - 维基百科
简单来说,类是用于创建对象的蓝图。
注意: JavaScript 对象是具有属性和方法的实体。
让我们借助这个例子来理解类 -
类就像模板。我们可以看到图中有一个 Car 类,它有一个属性 color,但我们没有指定具体是哪种颜色。
借助此类,我们可以创建具有特定颜色的不同对象,例如,如果我们将红色作为颜色参数传递,则会创建一辆红色汽车(即具有红色属性的对象)。
我们可以用类定义来定义什么? -
我们可以借助类定义来定义两个主要领域 -
-
实例属性 -
> 对象将具有的内容。
例如:名称、颜色等。 -
实例方法 -
> 对象将执行的操作。
例如:加法、面积计算等(任何函数)
注意:实例是对象的具体表示,或者我们可以说实例是使用特定类创建的对象。
类语法 -
我们先看一下代码,然后逐一讨论它的各个部分 -
class Person {
constructor(personName) {
this.name = personName;
}
sayHi() {
console.log(`Hi ${this.name}`);
}
}
// Usage:
let person1 = new Person("Alok");
person1.sayHi(); //Output - Hi Alok
我们要使用class关键字来创建一个类,后面跟着一个常规以大写字母开头的类名,即上面代码中的Person。
类定义位于两个花括号 {}之间。
每个类都有一个构造函数,构造函数基本上是一种在对象生命周期内仅运行一次的方法,特别是在创建对象时。
构造函数用于设置对象,即定义对象的状态(属性)。
在此.name = personName -
this指的是正在创建的当前对象。
name指的是属性名称。
personName是创建对象时传递的参数。
此外,sayHi()是一种具有一些功能的方法。
让我们看看如何使用类创建对象 -
我们使用带有类的new 关键字创建一个对象,如在此代码中,我们使用 Person 类创建了一个person1对象。
另外,我们在创建对象时将“Alok”作为参数传递给构造函数方法。
我们使用person1.sayHi()调用了sayHi()方法,该方法运行方法内部的代码并给出输出Hi Alok。
让我们再看一个例子 -
class Rectangle {
constructor(length, breadth) {
this.length = length;
this.breadth = breadth;
}
area() {
return this.length * this.breadth;
}
}
let rectangle1 = new Rectangle(4, 5);
rectangle1.area(); // gives Output: 20
在这个例子中,我们创建了一个带有参数4和5 的rectangular1对象。
area()方法使用存储在属性中的这些参数来查找面积(长度*宽度)并返回它。
getter 和 setter
Getters 和 Setters 基本上用于定义类中的方法,然后像属性一样使用。
让我们通过一个例子来理解这些 -
class Square {
constructor(side) {
this.side = side;
}
get area() {
return this.side * this.side;
}
set area(area) {
this.side = Math.sqrt(area);
}
}
let square1 = new Square(4);
console.log(square1.area); // gives output: 16
square1.area = 25;
console.log(square1.side); // gives output: 5
要使用 getter,我们必须使用get关键字,然后定义方法,然后我们可以将其作为属性调用(square1.area - 注意,在调用 area 方法时我们没有 ())。
而要使用 setter,我们使用set关键字,然后定义方法,然后通过直接将参数分配给它来调用它,就像在属性中一样(square1.area = 25 - 注意我们不在这里传递参数;而是直接分配它)。
静态方法
静态方法在类中定义,但不会被创建的对象使用或成为其一部分。
或者,简单地说,静态方法不需要创建类的实例才能使用。
静态方法也称为辅助方法。
让我们通过一个例子来理解这一点 -
class Temp {
constructor() {
}
static isEqual(a, b) {
return a === b;
}
}
Temp.isEqual(4,5); // returns false
Temp.isEqual(4,4); // returns true
静态方法是使用 static 关键字后跟方法定义(即static isEqual())来定义的。
可以使用类名直接调用静态方法(即Temp.isEqual())。
正如上面所见,我们不需要创建对象来使用静态方法。
另外,我们可以在调用静态方法时传递对象。
让我们看一个例子 -
class Temp {
constructor(value) {
this.value = value;
}
static isEquals(Obj1, Obj2) {
return Obj1.value === Obj2.value;
}
}
let temp1 = new Temp(4);
let temp2 = new Temp(6);
let temp3 = new Temp(4);
Temp.isEquals(temp1,temp2); // returns false
Temp.isEquals(temp1,temp3); // returns true
在这里您可以看到我们将对象作为参数传递给静态方法,该方法直接使用类名调用。
然后该方法使用objectName.value访问每个值属性并返回结果。
继承和扩展
借助继承,一个类可以扩展另一个类。或者,简单地说,一个类可以访问另一个类的方法,也可以拥有自己的方法。
让我们借助这张图片来理解这一点 -
在上图中,Child 类扩展了 Parent 类。我们可以看到,Child 类可以访问 Parent 类的方法(例如 add() 和 multiply() );此外,它还有自己的方法(例如 divide() 和 area() )。
让我们借助一个例子来理解继承。
首先看一下代码,然后我们逐一讨论它的各个部分 -
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`Hi!!! this is ${this.name} and I'm ${this.age} years old.`);
}
}
class Programmer extends Person {
constructor(name, age, role) {
super(name, age);
this.role = role;
}
info() {
this.sayHi();
console.log(`And I'm a ${this.role}`);
}
}
let person1 = new Person("Aman", 20);
let programmer1 = new Programmer("Alok", 21,
"Web Developer");
这里我们有一个Person类,它有一个接受name和age参数的构造函数。此外,它还有一个名为sayHi()的方法,它的作用是console.log输出“嗨!!!我是name,我今年age岁。”( name 和 age 是创建对象时传递的参数)。
接下来,我们有另一个名为Programmer的类。一个类可以使用extends 关键字加上要继承的类名来继承另一个类。就像这里一样,Programmer 类扩展了 Person 类。
程序员类有一个构造函数,接受name、age和role参数。super关键字用于调用 Person 类的构造函数。现在它不仅拥有 Person 类的属性,还拥有自己的属性—— role。
Programmer 类有一个方法info(),它调用 Person 类的方法sayHi()(因为现在 Programmer 类可以访问 Person 类了)。此外,console.log输出“And I'm a role ”(role 是创建对象时传递的参数)。
我们还创建了两个对象person1和programme1,分别属于 Person 类和 Programmer 类。
现在让我们看看对它们的不同操作及其结果 -
这里可以看到,programmer1 对象拥有 Person 类的属性:name和age。此外,它还有自己的属性:role。
这里我们使用 Person 类的对象调用了sayHi()方法。
这里我们使用 Programmer 类的对象调用了info()方法,你可以看到它在创建 programme1 对象时使用传递的参数调用并执行了 Person 类的sayHi()方法;此外,它还执行了自己的 console.log 输出。
这里可以看到,我们使用 Programmer 类的对象调用了 Person 类的sayHi()方法(因为 Programmer 类扩展了 Person 类,并且能够访问其方法)。此外,它还接收了在创建 progammer1 时传递的参数,因为我们使用 Programmer 类的对象调用了sayHi()方法。
但是我们不能使用 Person 类的对象访问 Programmer 类的方法,因为 Parent 类无法访问 Child 类。
多态性
多态性允许我们覆盖父类的方法。
让我们通过一个例子来理解它 -
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(`${this.name} is an Animal.`);
}
}
class Dogs extends Animal {
constructor(name) {
super(name);
}
sayName() {
console.log(`${this.name} is a Dog.`);
}
}
let animal1 = new Animal("Tiger");
let dog1 = new Dogs("Bull Dog");
这里父类(动物)和子类(狗)都有相同的方法sayName()。
我们之前已经看到,我们可以使用 Child 类的对象调用 Parent 类的方法,但在这种情况下,两个方法具有相同的名称。
让我们看看当我们调用它们时会发生什么 -
它运行正常;现在,让我们看看当我们使用dog1对象调用sayName()方法时会发生什么-
在这里您可以看到 Dog 类的 sayName() 方法覆盖了 Animal 类的 sayName() 方法。
这就是多态性允许覆盖父类方法的方式。
我尽量保持简单和精确,感谢您阅读到最后,而且我对未来有很多计划,所以请继续关注🙂
如果您发现这有用,那么您可以与其他人分享:)
欢迎留言,我们聊聊吧👋👋👋
阅读JavaScript 模块入门系列的下一篇博客👉