JavaScript类(Class)核心知识点
编程小白也能理解的JavaScript类(class)详解
面向对象
类是实现面向对象编程(OOP)的基础
代码复用
通过类实现代码复用和组织
继承机制
使用extends实现类之间的继承
类的基本概念
类(Class)是创建对象的模板,它定义了对象的属性和方法。
想象类就像建筑蓝图,而对象是按照蓝图建造的实际房屋。
class Person { // 定义一个Person类
constructor(name, age) { // 构造方法
this.name = name; // 实例属性
this.age = age;
}
introduce() { // 实例方法
return `大家好,我是${this.name},今年${this.age}岁。`;
}
}
constructor(name, age) { // 构造方法
this.name = name; // 实例属性
this.age = age;
}
introduce() { // 实例方法
return `大家好,我是${this.name},今年${this.age}岁。`;
}
}
温馨提示: JavaScript中的类本质上是基于原型的继承的语法糖,提供了更清晰、更面向对象的写法。
构造函数
constructor 是类的特殊方法,在创建类的新实例时自动调用。
它主要用于初始化对象的属性,每个类只能有一个构造函数。
class Car {
constructor(brand, year) {
this.brand = brand;
this.year = year;
this.isNew = year >= 2020;
}
}
// 创建实例
const myCar = new Car(‘Toyota’, 2022);
constructor(brand, year) {
this.brand = brand;
this.year = year;
this.isNew = year >= 2020;
}
}
// 创建实例
const myCar = new Car(‘Toyota’, 2022);
使用 new 关键字创建类的实例:
- 创建一个新的空对象
- 将新对象的原型指向类的原型
- 执行构造函数,并将新对象绑定到
this
- 返回新创建的对象
方法与属性
实例方法
在类中定义的方法会被添加到类的原型(prototype)中,所有实例共享这些方法。
class Circle {
constructor(radius) {
this.radius = radius;
}
area() { // 实例方法
return Math.PI * this.radius ** 2;
}
}
constructor(radius) {
this.radius = radius;
}
area() { // 实例方法
return Math.PI * this.radius ** 2;
}
}
静态方法
使用 static 关键字定义,属于类本身而不是实例。
class MathUtils {
static square(x) { // 静态方法
return x * x;
}
}
// 调用静态方法
MathUtils.square(5); // 25
static square(x) { // 静态方法
return x * x;
}
}
// 调用静态方法
MathUtils.square(5); // 25
继承
使用 extends 关键字实现类之间的继承。
子类可以继承父类的属性和方法,也可以添加自己的属性和方法。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} 发出声音。`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
speak() { // 方法重写
console.log(`${this.name} 汪汪叫!`);
}
}
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} 发出声音。`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
speak() { // 方法重写
console.log(`${this.name} 汪汪叫!`);
}
}
super关键字: 用于调用父类的构造函数或方法。在子类构造函数中,super
必须在this
之前调用。
Getter与Setter
用于定义获取和设置属性值的特殊方法,提供对属性访问的控制。
class Temperature {
constructor(celsius) {
this._celsius = celsius; // 约定用下划线表示内部属性
}
get celsius() { // getter
return this._celsius;
}
set celsius(value) { // setter
if (value < -273.15) {
console.log(“温度不能低于绝对零度!”);
return;
}
this._celsius = value;
}
get fahrenheit() { // 计算属性
return this._celsius * 9/5 + 32;
}
}
constructor(celsius) {
this._celsius = celsius; // 约定用下划线表示内部属性
}
get celsius() { // getter
return this._celsius;
}
set celsius(value) { // setter
if (value < -273.15) {
console.log(“温度不能低于绝对零度!”);
return;
}
this._celsius = value;
}
get fahrenheit() { // 计算属性
return this._celsius * 9/5 + 32;
}
}
使用getter/setter的好处:
- 验证数据
- 计算属性
- 封装内部实现
- 提供更友好的API
私有字段与方法
在类中,可以使用 # 前缀来定义私有字段和私有方法。
私有成员只能在类的内部访问,外部无法直接访问。
class BankAccount {
#balance = 0; // 私有字段
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
withdraw(amount) {
if (amount > 0 && amount <= this.#balance) {
this.#balance -= amount;
return amount;
}
return 0;
}
#logTransaction(type, amount) { // 私有方法
console.log(`${type} ${amount}元`);
}
get balance() {
return this.#balance;
}
}
#balance = 0; // 私有字段
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
withdraw(amount) {
if (amount > 0 && amount <= this.#balance) {
this.#balance -= amount;
return amount;
}
return 0;
}
#logTransaction(type, amount) { // 私有方法
console.log(`${type} ${amount}元`);
}
get balance() {
return this.#balance;
}
}
注意: 私有字段是ES2022的新特性,在不支持的环境中可能需要转译器(如Babel)来处理。
类的实用技巧
封装与抽象
类可以把数据和操作数据的方法封装在一起,对外只暴露必要的接口。
多态性
子类可以重写父类的方法,实现不同的行为。
class Shape {
area() { // 抽象方法(在JS中并没有真正的抽象方法)
throw new Error(‘子类必须实现area方法’);
}
}
class Square extends Shape {
constructor(side) {
super();
this.side = side;
}
area() { // 实现多态
return this.side ** 2;
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() { // 实现多态
return Math.PI * this.radius ** 2;
}
}
area() { // 抽象方法(在JS中并没有真正的抽象方法)
throw new Error(‘子类必须实现area方法’);
}
}
class Square extends Shape {
constructor(side) {
super();
this.side = side;
}
area() { // 实现多态
return this.side ** 2;
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() { // 实现多态
return Math.PI * this.radius ** 2;
}
}
类的扩展
可以给现有的类添加新方法(但通常不建议修改内置类的原型)
// 给Array类添加一个新方法
class MyArray extends Array {
last() {
return this[this.length – 1];
}
}
const arr = new MyArray(1, 2, 3);
console.log(arr.last()); // 3
class MyArray extends Array {
last() {
return this[this.length – 1];
}
}
const arr = new MyArray(1, 2, 3);
console.log(arr.last()); // 3
类的优势
- 代码组织结构更清晰
- 提高代码复用性
- 实现封装和信息隐藏
- 支持继承和多态
注意事项
- 类定义不会被提升(必须先定义后使用)
- 类中的方法不需要function关键字
- 类的方法之间不需要逗号分隔
- 类本质仍然是函数和原型继承
JavaScript 类(Class) 知识点总结 | 面向对象编程基础 | 适合编程小白的学习资料
© 2023 JavaScript学习指南 | 使用现代浏览器体验最佳效果