在 JavaScript 面向对象编程中,类(Class) 是创建对象的模板,而继承(Inheritance) 则允许子类复用父类的属性和方法并扩展新功能。ES6 引入 class 关键字规范化了类的定义,通过 extends 和 super 实现继承,ES2022 进一步引入私有字段增强封装性,形成了完整的面向对象编程体系。
ES6 采用 class 关键字定义类,内部通过 constructor 方法初始化实例属性,并可直接定义实例方法。与传统构造函数模式相比,类语法更贴近面向对象的直觉表达。
基础类定义示例(以动物类 Animal 为例):
class Animal {
// 构造函数:初始化实例属性
constructor(name) {
this.name = name; // 公共属性:实例可直接访问
}
// 实例方法:定义动物发声行为
speak() {
console.log(`${this.name} makes a noise.`);
}
}
// 创建实例并调用方法
const animal = new Animal("Generic Animal");
animal.speak(); // 输出:"Generic Animal makes a noise."
类定义要点:
constructor 是类的默认构造函数,实例化时自动执行,用于初始化 this 指向的实例属性。 function 关键字),会被添加到类的原型对象上,供所有实例共享。通过 extends 关键字可实现子类对父类的继承,子类通过 super() 调用父类构造函数,从而复用父类属性和方法,并可通过重写方法实现功能扩展。
动物类与子类案例(以 Dog 继承 Animal 为例):
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
// 子类 Dog 继承父类 Animal
class Dog extends Animal {
// 构造函数:通过 super 调用父类构造函数
constructor(name, breed) {
super(name); // 必须先调用 super(),再访问 this
this.breed = breed; // 子类新增属性
}
// 方法重写:覆盖父类 speak 方法
speak() {
console.log(`${this.name} (${this.breed}) barks: Woof!`);
}
// 子类新增方法
fetch() {
console.log(`${this.name} fetches the ball.`);
}
}
// 实例化子类并调用方法
const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // 输出:"Buddy (Golden Retriever) barks: Woof!"
dog.fetch(); // 输出:"Buddy fetches the ball."
继承核心逻辑:
extends 声明继承关系,子类原型链指向父类。 super() 在子类构造函数中必须优先调用,用于初始化父类属性;若子类未定义构造函数,会默认调用 super()。 super.method() 在子类方法中调用父类方法(如 super.speak())。ES2022(ES13)引入私有类字段,通过 # 前缀声明,仅允许在类内部访问,有效隔离类的内部实现与外部接口,强化封装性。
计数器类(Counter)私有字段示例:
class Counter {
#count = 0; // 私有字段:仅类内部可访问
// 公共方法:操作私有字段
increment() {
this.#count++; // 类内部可访问私有字段
}
// 公共方法:读取私有字段
getCount() {
return this.#count;
}
// 静态方法:检查实例是否包含私有字段
static hasPrivateField(instance) {
return #count in instance; // 使用 #field in 语法检查
}
}
// 使用计数器类
const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // 输出:1
console.log(counter.#count); // 语法错误:私有字段无法从外部访问
// 检查私有字段
console.log(Counter.hasPrivateField(counter)); // 输出:true
私有字段特性:
#count 无法通过实例(如 counter.#count)或原型链访问,仅类内部方法可读写。 increment 方法可限制计数逻辑)。 #field in instance 可判断对象是否为类的实例(比 instanceof 更严格,依赖私有字段标识)。ES6 类语法通过 class、extends 和 super 简化了面向对象编程的实现,而私有字段(#)的引入则补齐了 JavaScript 在封装性上的短板。通过类定义标准化、继承机制清晰化和内部状态私有化,JavaScript 面向对象编程更贴近传统面向对象语言的设计思想,同时保持了动态语言的灵活性。在实际开发中,合理使用类与继承可提升代码复用性,而私有字段则能有效保护类的内部实现,降低外部依赖风险。