1. ES6类的基本语法

1.1 类的定义

// 基本类定义
class Person {// 构造函数constructor(name, age) {this.name = name;this.age = age;}// 实例方法sayHello() {return `Hello, I'm ${this.name}, ${this.age} years old.`;}// 静态方法static createAnonymous(age) {return new Person('Anonymous', age);}
}// 使用类
const person1 = new Person('Alice', 25);
console.log(person1.sayHello()); // Hello, I'm Alice, 25 years old.

1.2 类的特性

class Student {constructor(name, grade) {this.name = name;this.grade = grade;this._courses = []; // 私有属性约定}// Getter和Setterget courses() {return this._courses;}set courses(courses) {if (Array.isArray(courses)) {this._courses = courses;} else {throw new Error('Courses must be an array');}}// 计算属性get gradeLevel() {if (this.grade >= 90) return 'A';if (this.grade >= 80) return 'B';if (this.grade >= 70) return 'C';return 'F';}// 方法可以返回this,支持链式调用addCourse(course) {this._courses.push(course);return this; // 返回this以支持链式调用}removeCourse(course) {this._courses = this._courses.filter(c => c !== course);return this;}
}// 使用示例
const student = new Student('Bob', 85);
student.addCourse('Math').addCourse('Science');
console.log(student.courses); // ['Math', 'Science']
console.log(student.gradeLevel); // 'B'

2. 继承机制

2.1 基本继承

// 父类
class Animal {constructor(name, species) {this.name = name;this.species = species;this._health = 100;}eat(food) {console.log(`${this.name} is eating ${food}`);this._health += 10;}sleep() {console.log(`${this.name} is sleeping`);this._health += 20;}get health() {return this._health;}
}// 子类继承父类
class Dog extends Animal {constructor(name, breed) {super(name, 'Dog'); // 调用父类构造函数this.breed = breed;this._loyalty = 100;}// 重写父类方法eat(food) {super.eat(food); // 调用父类方法if (food === 'bone') {console.log(`${this.name} is wagging tail`);}}// 新增方法bark() {console.log(`${this.name} says: Woof!`);}fetch() {console.log(`${this.name} is fetching the ball`);this._health -= 5;}
}// 另一个子类
class Cat extends Animal {constructor(name, color) {super(name, 'Cat');this.color = color;this._mood = 'calm';}// 重写父类方法sleep() {console.log(`${this.name} is napping in the sun`);this._health += 25; // 猫睡觉恢复更多健康值}meow() {console.log(`${this.name} says: Meow~`);}climb() {console.log(`${this.name} is climbing a tree`);this._health -= 3;}
}// 使用继承
const dog = new Dog('Buddy', 'Golden Retriever');
const cat = new Cat('Whiskers', 'Orange');dog.eat('bone'); // Buddy is eating bone, Buddy is wagging tail
dog.bark(); // Buddy says: Woof!cat.sleep(); // Whiskers is napping in the sun
cat.meow(); // Whiskers says: Meow~

2.2 多级继承

// 多级继承示例
class Vehicle {constructor(brand, model) {this.brand = brand;this.model = model;this._speed = 0;}start() {console.log(`${this.brand} ${this.model} is starting`);}accelerate(amount) {this._speed += amount;console.log(`Speed: ${this._speed} km/h`);}brake(amount) {this._speed = Math.max(0, this._speed - amount);console.log(`Speed: ${this._speed} km/h`);}
}class Car extends Vehicle {constructor(brand, model, doors) {super(brand, model);this.doors = doors;this._fuel = 100;}refuel(amount) {this._fuel = Math.min(100, this._fuel + amount);console.log(`Fuel level: ${this._fuel}%`);}
}class ElectricCar extends Car {constructor(brand, model, doors, batteryCapacity) {super(brand, model, doors);this.batteryCapacity = batteryCapacity; // kWhthis._batteryLevel = 100;}// 重写refuel方法refuel(amount) {throw new Error('Electric cars cannot be refueled with fuel');}charge(amount) {this._batteryLevel = Math.min(100, this._batteryLevel + amount);console.log(`Battery level: ${this._batteryLevel}%`);}// 重写accelerate方法accelerate(amount) {if (this._batteryLevel <= 0) {console.log('Battery empty! Cannot accelerate');return;}super.accelerate(amount);this._batteryLevel -= amount * 0.1; // 消耗电量}
}// 使用多级继承
const tesla = new ElectricCar('Tesla', 'Model 3', 4, 75);
tesla.start(); // Tesla Model 3 is starting
tesla.accelerate(50); // Speed: 50 km/h
tesla.charge(30); // Battery level: 80%

3. 高级特性

3.1 静态成员

class MathUtils {// 静态属性static PI = 3.14159;static E = 2.71828;// 静态方法static add(a, b) {return a + b;}static multiply(a, b) {return a * b;}static circleArea(radius) {return this.PI * radius * radius;}static factorial(n) {if (n <= 1) return 1;return n * this.factorial(n - 1);}
}// 静态成员的继承
class AdvancedMath extends MathUtils {static power(base, exponent) {return Math.pow(base, exponent);}static fibonacci(n) {if (n <= 1) return n;return this.add(this.fibonacci(n - 1), this.fibonacci(n - 2));}
}// 使用静态成员
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.add(5, 3)); // 8
console.log(AdvancedMath.circleArea(5)); // 78.53975
console.log(AdvancedMath.fibonacci(10)); // 55

3.2 私有字段和方法

class BankAccount {// 私有字段#balance = 0;#transactions = [];#accountNumber;constructor(initialBalance = 0) {this.#balance = initialBalance;this.#accountNumber = this.#generateAccountNumber();this.#addTransaction('Account created', initialBalance);}// 私有方法#generateAccountNumber() {return 'ACC' + Math.floor(Math.random() * 1000000).toString().padStart(6, '0');}#addTransaction(description, amount) {this.#transactions.push({date: new Date(),description,amount,balance: this.#balance});}// 公共方法访问私有成员deposit(amount) {if (amount <= 0) {throw new Error('Deposit amount must be positive');}this.#balance += amount;this.#addTransaction('Deposit', amount);console.log(`Deposited $${amount}. New balance: $${this.#balance}`);}withdraw(amount) {if (amount <= 0) {throw new Error('Withdrawal amount must be positive');}if (amount > this.#balance) {throw new Error('Insufficient funds');}this.#balance -= amount;this.#addTransaction('Withdrawal', -amount);console.log(`Withdrew $${amount}. New balance: $${this.#balance}`);}getBalance() {return this.#balance;}getTransactions() {return [...this.#transactions]; // 返回副本,防止外部修改}// 静态方法static transfer(fromAccount, toAccount, amount) {fromAccount.withdraw(amount);toAccount.deposit(amount);console.log(`Transferred $${amount} from ${fromAccount.#accountNumber} to ${toAccount.#accountNumber}`);}
}// 使用私有字段的类
const account1 = new BankAccount(1000);
const account2 = new BankAccount(500);account1.deposit(200); // Deposited $200. New balance: $1200
account1.withdraw(150); // Withdrew $150. New balance: $1050// 尝试直接访问私有字段会报错
// console.log(account1.#balance); // SyntaxError// 使用静态方法转账
BankAccount.transfer(account1, account2, 300);

3.3 抽象类模拟

// 模拟抽象类
class Shape {constructor(color) {if (new.target === Shape) {throw new Error('Shape is an abstract class and cannot be instantiated');}this.color = color;}// 抽象方法(子类必须实现)getArea() {throw new Error('getArea method must be implemented by subclass');}getPerimeter() {throw new Error('getPerimeter method must be implemented by subclass');}// 公共方法describe() {return `This is a ${this.color} shape with area ${this.getArea()} and perimeter ${this.getPerimeter()}`;}
}class Rectangle extends Shape {constructor(width, height, color) {super(color);this.width = width;this.height = height;}getArea() {return this.width * this.height;}getPerimeter() {return 2 * (this.width + this.height);}// 新增方法isSquare() {return this.width === this.height;}
}class Circle extends Shape {constructor(radius, color) {super(color);this.radius = radius;}getArea() {return Math.PI * this.radius * this.radius;}getPerimeter() {return 2 * Math.PI * this.radius;}// 新增方法getDiameter() {return 2 * this.radius;}
}// 使用抽象类
const rectangle = new Rectangle(5, 3, 'red');
const circle = new Circle(4, 'blue');console.log(rectangle.describe()); // This is a red shape with area 15 and perimeter 16
console.log(circle.describe()); // This is a blue shape with area 50.26548245743669 and perimeter 25.132741228718345// 以下会抛出错误
// const shape = new Shape('green'); // Error: Shape is an abstract class

4. 实际应用案例

4.1 用户管理系统

// 用户基类
class User {static userCount = 0;constructor(username, email) {this.username = username;this.email = email;this.createdAt = new Date();this.#id = ++User.userCount;this.#loginHistory = [];}#id;#loginHistory;get id() {return this.#id;}get loginHistory() {return [...this.#loginHistory];}login() {const loginTime = new Date();this.#loginHistory.push(loginTime);console.log(`${this.username} logged in at ${loginTime}`);}logout() {console.log(`${this.username} logged out`);}static getUserCount() {return User.userCount;}
}// 管理员用户
class Admin extends User {constructor(username, email, permissions = []) {super(username, email);this.permissions = permissions;this.#adminLevel = 1;}#adminLevel;get adminLevel() {return this.#adminLevel;}set adminLevel(level) {if (level >= 1 && level <= 5) {this.#adminLevel = level;} else {throw new Error('Admin level must be between 1 and 5');}}// 重写login方法login() {super.login();console.log(`Admin ${this.username} has level ${this.adminLevel} access`);}// 管理员特有方法banUser(user) {console.log(`${this.username} banned user ${user.username}`);}promoteUser(user, newLevel) {if (user instanceof Admin) {user.adminLevel = newLevel;console.log(`${this.username} promoted ${user.username} to level ${newLevel}`);} else {console.log(`${user.username} is not an admin`);}}
}// 普通用户
class RegularUser extends User {constructor(username, email, preferences = {}) {super(username, email);this.preferences = preferences;this.#points = 0;}#points;get points() {return this.#points;}addPoints(amount) {this.#points += amount;console.log(`${this.username} earned ${amount} points. Total: ${this.#points}`);}redeemPoints(amount) {if (amount > this.#points) {throw new Error('Insufficient points');}this.#points -= amount;console.log(`${this.username} redeemed ${amount} points. Remaining: ${this.#points}`);}
}// 使用用户管理系统
const admin = new Admin('admin', 'admin@site.com', ['read', 'write', 'delete']);
const user1 = new RegularUser('john', 'john@email.com', { theme: 'dark' });
const user2 = new RegularUser('jane', 'jane@email.com');admin.login(); // admin logged in at [date], Admin admin has level 1 access
user1.login(); // john logged in at [date]
user1.addPoints(100); // john earned 100 points. Total: 100admin.banUser(user2); // admin banned user jane
admin.promoteUser(admin, 3); // admin promoted admin to level 3console.log(`Total users: ${User.getUserCount()}`); // Total users: 3

4.2 游戏角色系统

// 游戏角色基类
class Character {constructor(name, health, mana) {this.name = name;this.maxHealth = health;this.health = health;this.maxMana = mana;this.mana = mana;this.level = 1;this.experience = 0;}takeDamage(damage) {this.health = Math.max(0, this.health - damage);console.log(`${this.name} took ${damage} damage. Health: ${this.health}/${this.maxHealth}`);if (this.health <= 0) {this.die();}}heal(amount) {this.health = Math.min(this.maxHealth, this.health + amount);console.log(`${this.name} healed for ${amount}. Health: ${this.health}/${this.maxHealth}`);}gainExperience(amount) {this.experience += amount;console.log(`${this.name} gained ${amount} experience`);// 检查是否升级const expToNextLevel = this.level * 100;if (this.experience >= expToNextLevel) {this.levelUp();}}levelUp() {this.level++;this.maxHealth += 20;this.health = this.maxHealth;this.maxMana += 10;this.mana = this.maxMana;console.log(`${this.name} leveled up to level ${this.level}!`);}die() {console.log(`${this.name} has been defeated!`);}getStatus() {return {name: this.name,level: this.level,health: this.health,maxHealth: this.maxHealth,mana: this.mana,maxMana: this.maxMana,experience: this.experience};}
}// 战士类
class Warrior extends Character {constructor(name) {super(name, 150, 50);this.strength = 20;this.defense = 15;}attack(target) {const damage = this.strength + Math.floor(Math.random() * 10);console.log(`${this.name} attacks ${target.name} for ${damage} damage!`);target.takeDamage(damage);}// 战士特有技能shieldBlock() {if (this.mana >= 20) {this.mana -= 20;const blockAmount = this.defense * 2;console.log(`${this.name} uses Shield Block, reducing next damage by ${blockAmount}`);// 这里可以添加临时防御增益效果return blockAmount;} else {console.log(`${this.name} doesn't have enough mana for Shield Block`);return 0;}}
}// 法师类
class Mage extends Character {constructor(name) {super(name, 80, 200);this.intelligence = 25;this.spellPower = 18;}castSpell(target, spellName) {const spellCosts = {'Fireball': 30,'Ice Lance': 25,'Heal': 40};const spellDamage = {'Fireball': this.intelligence + 15,'Ice Lance': this.intelligence + 10,'Heal': this.spellPower + 20};const manaCost = spellCosts[spellName];if (!manaCost) {console.log(`${spellName} is not a valid spell`);return;}if (this.mana < manaCost) {console.log(`${this.name} doesn't have enough mana to cast ${spellName}`);return;}this.mana -= manaCost;if (spellName === 'Heal') {target.heal(spellDamage[spellName]);console.log(`${this.name} casts ${spellName} on ${target.name}`);} else {const damage = spellDamage[spellName];console.log(`${this.name} casts ${spellName} on ${target.name} for ${damage} damage!`);target.takeDamage(damage);}}// 法师特有技能manaShield() {const shieldAmount = this.intelligence;this.mana = Math.max(0, this.mana - 50);console.log(`${this.name} creates a Mana Shield that absorbs ${shieldAmount} damage`);// 这里可以添加临时护盾效果return shieldAmount;}
}// 使用游戏角色系统
const warrior = new Warrior('Conan');
const mage = new Mage('Merlin');console.log('=== Battle Start ===');
warrior.attack(mage); // Conan attacks Merlin for X damage!
mage.castSpell(warrior, 'Fireball'); // Merlin casts Fireball on Conan for Y damage!
mage.castSpell(mage, 'Heal'); // Merlin casts Heal on Merlinconsole.log('\n=== Character Status ===');
console.log(warrior.getStatus());
console.log(mage.getStatus());// 战士使用技能
warrior.shieldBlock();// 法师使用技能
mage.manaShield();// 获得经验值
warrior.gainExperience(150);
mage.gainExperience(120);

5. 最佳实践和注意事项

5.1 设计原则

// 单一职责原则
class Logger {log(message) {console.log(`[${new Date().toISOString()}] ${message}`);}error(message) {console.error(`[ERROR] ${message}`);}
}class DataProcessor {processData(data) {// 数据处理逻辑return data.map(item => item * 2);}
}// 开闭原则
class PaymentProcessor {processPayment(amount, method) {if (method === 'credit') {return this.processCreditCard(amount);} else if (method === 'paypal') {return this.processPayPal(amount);}throw new Error('Unsupported payment method');}processCreditCard(amount) {console.log(`Processing $${amount} via credit card`);return true;}processPayPal(amount) {console.log(`Processing $${amount} via PayPal`);return true;}
}// 依赖倒置原则
class NotificationService {constructor(sender) {this.sender = sender;}send(message) {this.sender.send(message);}
}class EmailSender {send(message) {console.log(`Sending email: ${message}`);}
}class SMSSender {send(message) {console.log(`Sending SMS: ${message}`);}
}// 使用
const emailService = new NotificationService(new EmailSender());
const smsService = new NotificationService(new SMSSender());emailService.send('Hello via email');
smsService.send('Hello via SMS');

5.2 性能优化

// 避免在构造函数中创建函数
class OptimizedClass {constructor(name) {this.name = name;// ❌ 避免这样做 - 每次实例化都会创建新函数// this.greet = function() {//     return `Hello, ${this.name}`;// };}// ✅ 正确做法 - 方法定义在原型上greet() {return `Hello, ${this.name}`;}// 对于需要闭包的情况,可以使用私有字段#boundMethod;get boundGreet() {if (!this.#boundMethod) {this.#boundMethod = this.greet.bind(this);}return this.#boundMethod;}
}// 使用WeakMap实现真正的私有属性(兼容性考虑)
const privateData = new WeakMap();class PrivateClass {constructor(name) {privateData.set(this, {name: name,secret: 'very secret'});}getName() {return privateData.get(this).name;}setName(name) {privateData.get(this).name = name;}
}

总结

ES6的类和继承机制为JavaScript带来了更现代化的面向对象编程体验:

  1. 语法简洁class关键字提供了清晰的类定义语法
  2. 继承简单extendssuper关键字简化了继承实现
  3. 私有成员#前缀支持真正的私有字段和方法
  4. 静态成员static关键字定义类级别的属性和方法
  5. getter/setter:支持属性访问器和修改器

这些特性使得JavaScript的面向对象编程更加直观和强大,同时保持了语言的灵活性。在实际开发中,合理使用这些特性可以创建出结构清晰、易于维护的代码。