搞定静态属性和方法,轻松理解 JavaScript 类的本质
2023-04-02 04:59:43
静态属性和方法:超越实例的共享数据和行为
在 JavaScript 中,静态属性和方法允许你创建属于类本身而不是其实例的数据和行为。这使得你可以存储和操纵整个类共享的信息,并定义在类级别执行的操作。
静态属性
超越实例的共享数据
静态属性属于类本身,而不是类的实例。无论创建多少个类的实例,它们都共享相同的静态属性。这意味着你可以存储对于整个类而言是公共的数据或配置,而无需为每个实例创建单独的副本。
代码示例:
class Car {
static numWheels = 4;
constructor(make, model) {
this.make = make;
this.model = model;
}
}
const car1 = new Car("Tesla", "Model S");
const car2 = new Car("Toyota", "Camry");
console.log(Car.numWheels); // 4
console.log(car1.numWheels); // undefined
在这个例子中,numWheels
是一个静态属性,它存储了汽车类的所有实例共享的车轮数量。
静态方法
超越实例的共享行为
静态方法也属于类本身,而不是类的实例。静态方法可以访问静态属性,但不能访问实例属性。静态方法通常用于执行与类本身相关但与特定实例无关的操作。
代码示例:
class Car {
static numWheels = 4;
constructor(make, model) {
this.make = make;
this.model = model;
}
static getCarInfo() {
return `This car has ${this.numWheels} wheels.`;
}
}
const car1 = new Car("Tesla", "Model S");
const car2 = new Car("Toyota", "Camry");
Car.getCarInfo(); // "This car has 4 wheels."
car1.drive(); // "The Tesla Model S is driving."
在这个例子中,getCarInfo
是一个静态方法,它返回有关汽车类的所有实例共享的车轮数量的信息。
访问控制
把控数据和行为的可见性
JavaScript 中的访问控制决定了属性和方法的可见性。静态属性和静态方法默认都是公开的,这意味着它们可以在任何地方访问。然而,你也可以使用访问控制修饰符来限制它们的可见性。
代码示例:
class Car {
#numWheels = 4; // 私有静态属性
constructor(make, model) {
this.make = make;
this.model = model;
}
static #getCarInfo() { // 私有静态方法
return `This car has ${this.#numWheels} wheels.`;
}
drive() {
console.log(`The ${this.make} ${this.model} is driving.`);
}
}
const car1 = new Car("Tesla", "Model S");
const car2 = new Car("Toyota", "Camry");
console.log(Car.#numWheels); // 报错:私有属性无法访问
console.log(Car.#getCarInfo()); // 报错:私有方法无法访问
car1.drive(); // "The Tesla Model S is driving."
在这个例子中,#numWheels
和 #getCarInfo
是私有的,这意味着它们只能在 Car
类内部访问。
封装
隐藏实现细节,彰显代码简洁性
封装是将数据和行为捆绑在一起,并隐藏实现细节的一种技术。静态属性和静态方法可以帮助你实现封装,让代码更加简洁和易于维护。
代码示例:
class Car {
#numWheels = 4;
constructor(make, model) {
this.make = make;
this.model = model;
}
static getCarInfo() {
return `This car has ${this.#numWheels} wheels.`;
}
drive() {
console.log(`The ${this.make} ${this.model} is driving.`);
}
}
const car1 = new Car("Tesla", "Model S");
const car2 = new Car("Toyota", "Camry");
console.log(Car.getCarInfo()); // "This car has 4 wheels."
car1.drive(); // "The Tesla Model S is driving."
在这个例子中,#numWheels
属性和 #getCarInfo
方法隐藏在 Car
类内部,只暴露了必要的接口(如 getCarInfo
静态方法和 drive
实例方法)。这使得代码更加简洁和易于维护。
多态
面向对象编程的核心奥义
多态是指在父类和子类的层次结构中,子类可以重写父类的方法,并提供不同的实现。静态属性和静态方法也可以支持多态,子类可以继承父类的静态属性和静态方法,并根据需要进行修改。
代码示例:
class Car {
static numWheels = 4;
static getCarInfo() {
return `This car has ${this.numWheels} wheels.`;
}
drive() {
console.log(`The ${this.make} ${this.model} is driving.`);
}
}
class ElectricCar extends Car {
static numWheels = 4; // 子类继承父类静态属性
static getCarInfo() { // 子类重写父类静态方法
return `This electric car has ${this.numWheels} wheels and zero emissions.`;
}
drive() { // 子类重写父类实例方法
console.log(`The ${this.make} ${this.model} is driving silently.`);
}
}
const car1 = new Car("Tesla", "Model S");
const electricCar1 = new ElectricCar("Tesla", "Model X");
console.log(Car.getCarInfo()); // "This car has 4 wheels."
console.log(ElectricCar.getCarInfo()); // "This electric car has 4 wheels and zero emissions."
car1.drive(); // "The Tesla Model S is driving."
electricCar1.drive(); // "The Tesla Model X is driving silently."
在这个例子中,ElectricCar
子类继承了 Car
父类的静态属性和静态方法,并重写了 getCarInfo
静态方法和 drive
实例方法以提供不同的实现。
代码复用
共享代码,提升开发效率
静态属性和静态方法可以帮助你实现代码复用。你可以在父类中定义静态属性和静态方法,然后在子类中继承它们。这样,子类就可以使用父类的静态属性和静态方法,而无需重新定义。
代码示例:
class Car {
static numWheels = 4;
static getCarInfo() {
return `This car has ${this.numWheels} wheels.`;
}
drive() {
console.log(`The ${this.make} ${this.model} is driving.`);
}
}
class ElectricCar extends Car {
static numWheels = 4; // 子类继承父类静态属性
static getCarInfo() { // 子类重写父类静态方法
return `This electric car has ${this.numWheels} wheels and zero emissions.`;
}
drive() { // 子类重写父类实例方法
console.log(`The ${this.make} ${this.model} is driving silently.`);
}
}
const car1 = new Car("Tesla", "Model S");
const electricCar1 = new ElectricCar("Tesla", "Model X");
console.log(Car.getCarInfo()); // "This car has 4 wheels."
console.log(ElectricCar.getCarInfo()); // "This electric car has 4 wheels and zero emissions."
car1.drive(); // "The Tesla Model S is driving."
electricCar1.drive(); // "The Tesla Model X is driving silently."
在这个例子中,ElectricCar
子类继承了 Car
父类的静态属性和静态方法,这意味着它可以访问和使用这些属性和方法,而无需重新定义它们。
代码可维护性
让代码更易于维护和扩展
静态属性和静态方法可以帮助你提高代码的可维护性。你可以在父类中定义静态属性和静态方法,然后在子类中继承它们。这样,子类就可以使用父类的静态属性和静态方法,而无需重新定义。这可以减少代码冗余,使代码更容易维护和扩展。
代码示例:
class Car {
static numWheels = 4;
static getCarInfo() {
return `This car has ${this.numWheels} wheels.`;
}
drive() {
console.log(`The ${this.make} ${this.model} is driving.`);
}
}
class ElectricCar extends Car {
static