Skip to content

在 JavaScript 中,class是用来实现面向对象编程的一种语法结构。通过类,开发者可以创建共享属性和方法的对象,简化复杂系统的代码组织。

一、基本概念

1. 定义类

在 JavaScript 中,class关键字定义了一个类。类的作用是作为对象的蓝图,允许我们创建相似的对象。构造函数 constructor 在实例化时被调用,用于设置对象的初始状态。例如:

javascript
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sayHello() {
        console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
    }
}

在这个例子中,Person 类定义了两个属性 nameage,以及一个方法 sayHello

2. 创建实例

要创建一个类的实例,我们使用 new 关键字:

javascript
let person1 = new Person('Alice', 30);
person1.sayHello();

在执行 new Person('Alice', 30) 时,构造函数会将传入的 'Alice'30 分别赋值给 nameage,生成一个拥有这些属性和方法的 Person 实例。

二、类的继承

1. 基本继承

通过 extends 关键字,JavaScript 支持类的继承,这让子类可以共享父类的属性和方法。

javascript
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age); // 调用父类的构造函数
        this.grade = grade;
    }
    sayGrade() {
        console.log(`I'm in grade ${this.grade}.`);
    }
}

这里,Student 继承了 Person 的属性和方法,同时定义了自己的属性 grade 和方法 sayGrade

2. 方法重写

子类可以重写父类的方法,以适应自身的需求:

javascript
class Student extends Person {
    sayHello() {
        console.log(`Hi, I'm ${this.name}, a student in grade ${this.grade}.`);
    }
}

Student 实例上调用 sayHello 时,将执行此重写后的方法,而不是父类中的 sayHello

三、静态方法和属性

1. 静态方法

静态方法用 static 定义,直接在类上调用,而不依赖于类的实例。

javascript
class MathUtils {
    static add(a, b) {
        return a + b;
    }
}
console.log(MathUtils.add(2, 3));

在这个例子中,addMathUtils 类的静态方法,可以直接通过类名调用。

2. 静态属性

JavaScript 中的类还支持静态属性。静态属性不属于某个实例,而是属于类本身。

javascript
class Counter {
    static count = 0;
    constructor() {
        Counter.count++;
    }
}
let c1 = new Counter();
let c2 = new Counter();
console.log(Counter.count);

每创建一个 Counter 实例,静态属性 count 都会加 1,该属性在所有实例间共享。

四、与传统函数构造器的比较

1. 函数构造器的定义

在 ES6 之前,JavaScript 主要通过函数构造器创建对象:

javascript
function OldPerson(name, age) {
    this.name = name;
    this.age = age;
    this.sayHello = function() {
        console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
    };
}
let oldPerson1 = new OldPerson('Bob', 40);
oldPerson1.sayHello();

函数构造器和类的写法相似,但函数构造器中的方法会在每个实例中重新定义,导致性能和内存占用不如 class 优化。

2. 语法糖的本质

class 在 JavaScript 中其实是基于原型的语法糖。它将方法和属性添加到类的原型对象上,如 Person.prototype.sayHello 指向 Person 类中定义的 sayHello 方法。这样的写法更贴近其他面向对象语言(如 Java、C#)的语法习惯,提升了代码可读性。

五、构造函数参数的理解

constructor 方法中,我们会看到 this.name = name; 的写法,理解这一点有助于掌握对象的初始化过程。比如:

javascript
class Person {
    constructor(name, age) {
        this.name = name; // 将参数 name 赋给实例的属性 name
        this.age = age;   // 将参数 age 赋给实例的属性 age
    }
}

new Person('Alice', 30) 时,nameage 的值分别为 'Alice'30。构造函数的参数会传递给实例的属性,初始化对象的状态,使每个实例拥有独立的属性值。

总结而言,通过 class 语法,JavaScript 的面向对象编程变得更加直观和规范化,也让代码组织和复用性得到了提升。