Search K
Appearance
Appearance
📊 SEO元描述:2024年最新ES6 class语法教程,详解class基本语法、extends继承、super关键字、静态方法、私有字段。包含完整代码示例,适合现代前端开发者掌握JavaScript面向对象编程。
核心关键词:ES6 class语法2024、JavaScript class教程、extends继承、super关键字、JavaScript面向对象编程
长尾关键词:ES6 class怎么使用、JavaScript class继承怎么实现、super关键字作用、JavaScript静态方法、ES2022私有字段
通过本节ES6 class语法,你将系统性掌握:
ES6 class是什么?这是ECMAScript 2015引入的类语法,提供了更清晰、更接近传统面向对象语言的类定义方式。ES6 class本质上是JavaScript原型继承的语法糖,但提供了更简洁和直观的语法。
💡 学习建议:理解class是语法糖很重要,它底层仍然使用原型继承机制
ES6 class使用class关键字定义类,constructor方法作为构造函数:
// 🎉 ES6 class基本语法
class Animal {
// 构造函数
constructor(name, age) {
this.name = name;
this.age = age;
this.colors = ['red', 'blue', 'green'];
}
// 实例方法
eat() {
console.log(`${this.name} is eating`);
}
sleep() {
console.log(`${this.name} is sleeping`);
}
// getter方法
get info() {
return `${this.name} is ${this.age} years old`;
}
// setter方法
set nickname(value) {
this._nickname = value;
}
get nickname() {
return this._nickname || this.name;
}
}
// 使用class创建实例
const animal1 = new Animal('Buddy', 3);
const animal2 = new Animal('Max', 2);
animal1.eat(); // Buddy is eating
console.log(animal1.info); // Buddy is 3 years old
animal1.nickname = 'Bud';
console.log(animal1.nickname); // Bud
// 验证class的本质
console.log(typeof Animal); // function
console.log(Animal.prototype.constructor === Animal); // true
console.log(animal1 instanceof Animal); // true// 传统构造函数方式
function AnimalOld(name, age) {
this.name = name;
this.age = age;
}
AnimalOld.prototype.eat = function() {
console.log(`${this.name} is eating`);
};
// ES6 class方式
class AnimalNew {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
console.log(`${this.name} is eating`);
}
}
// 两种方式本质相同
console.log(typeof AnimalOld); // function
console.log(typeof AnimalNew); // function// 🔴 class的重要特性演示
class Example {
constructor() {
console.log('Constructor called');
}
method() {
console.log('Method called');
}
}
// 1. 类声明不会提升
console.log(typeof Example); // function
// 2. 类内部自动严格模式
class StrictExample {
constructor() {
// 在严格模式下,this不会指向全局对象
console.log(this); // StrictExample实例,不是window
}
}
// 3. 类必须使用new调用
const example = new Example(); // ✅ 正确
// const example2 = Example(); // ❌ TypeError: Class constructor cannot be invoked without 'new'**extends关键字是什么?**这是ES6提供的继承关键字,用于创建类的子类。extends关键字使得JavaScript继承语法更加简洁和直观,内部实现了完整的原型链继承机制。
// 🎉 extends关键字基本用法
class Animal {
constructor(name, species) {
this.name = name;
this.species = species;
}
eat() {
console.log(`${this.name} is eating`);
}
sleep() {
console.log(`${this.name} is sleeping`);
}
makeSound() {
console.log(`${this.name} makes a sound`);
}
}
// 🔴 使用extends创建子类
class Dog extends Animal {
constructor(name, breed) {
// 必须先调用super()
super(name, 'Canine');
this.breed = breed;
}
// 重写父类方法
makeSound() {
console.log(`${this.name} barks`);
}
// 子类特有方法
fetch(item) {
console.log(`${this.name} fetches ${item}`);
}
}
class Cat extends Animal {
constructor(name, color) {
super(name, 'Feline');
this.color = color;
}
makeSound() {
console.log(`${this.name} meows`);
}
climb() {
console.log(`${this.name} climbs`);
}
}
// 使用继承的类
const dog = new Dog('Buddy', 'Golden Retriever');
const cat = new Cat('Whiskers', 'Orange');
dog.eat(); // Buddy is eating (继承方法)
dog.makeSound(); // Buddy barks (重写方法)
dog.fetch('ball'); // Buddy fetches ball (子类方法)
cat.eat(); // Whiskers is eating (继承方法)
cat.makeSound(); // Whiskers meows (重写方法)
cat.climb(); // Whiskers climbs (子类方法)
// 验证继承关系
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true// 🎉 多层继承示例
class Animal {
constructor(name) {
this.name = name;
}
breathe() {
console.log(`${this.name} is breathing`);
}
}
class Mammal extends Animal {
constructor(name, furColor) {
super(name);
this.furColor = furColor;
}
feedMilk() {
console.log(`${this.name} feeds milk to babies`);
}
}
class Dog extends Mammal {
constructor(name, furColor, breed) {
super(name, furColor);
this.breed = breed;
}
bark() {
console.log(`${this.name} barks`);
}
}
const dog = new Dog('Buddy', 'Golden', 'Retriever');
dog.breathe(); // Buddy is breathing (从Animal继承)
dog.feedMilk(); // Buddy feeds milk to babies (从Mammal继承)
dog.bark(); // Buddy barks (Dog特有方法)**super关键字是什么?**这是ES6提供的用于访问父类的关键字。super可以作为函数调用父类构造函数,也可以作为对象访问父类的方法和属性。
// 🎉 super作为函数调用父类构造函数
class Vehicle {
constructor(brand, model, year) {
this.brand = brand;
this.model = model;
this.year = year;
console.log('Vehicle constructor called');
}
}
class Car extends Vehicle {
constructor(brand, model, year, doors) {
// 🔴 必须在访问this之前调用super()
super(brand, model, year); // 调用父类构造函数
this.doors = doors;
console.log('Car constructor called');
}
}
const car = new Car('Toyota', 'Camry', 2024, 4);
// 输出:
// Vehicle constructor called
// Car constructor called
console.log(car.brand); // Toyota
console.log(car.doors); // 4// 🎉 super作为对象访问父类方法
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
move() {
console.log(`${this.name} moves`);
}
}
class Dog extends Animal {
speak() {
// 调用父类方法
super.speak();
console.log(`${this.name} also barks`);
}
move() {
// 扩展父类方法
super.move();
console.log(`${this.name} runs on four legs`);
}
playFetch() {
// 在子类方法中调用父类方法
console.log(`${this.name} is ready to play`);
super.speak();
}
}
const dog = new Dog('Buddy');
dog.speak();
// 输出:
// Buddy makes a sound
// Buddy also barks
dog.move();
// 输出:
// Buddy moves
// Buddy runs on four legs
dog.playFetch();
// 输出:
// Buddy is ready to play
// Buddy makes a sound// 🔴 super使用的重要规则
class Parent {
constructor(value) {
this.value = value;
}
method() {
return 'parent method';
}
}
class Child extends Parent {
constructor(value, extra) {
// ❌ 错误:必须先调用super()才能使用this
// this.extra = extra; // ReferenceError
// ✅ 正确:先调用super()
super(value);
this.extra = extra;
}
method() {
// ✅ 正确:在实例方法中使用super
return super.method() + ' extended';
}
static staticMethod() {
// ✅ 正确:在静态方法中使用super
return super.staticMethod ? super.staticMethod() : 'no parent static method';
}
}**静态方法是什么?**这是属于类本身而不是实例的方法。静态方法使用static关键字定义,只能通过类名调用,不能通过实例调用。
// 🎉 静态方法和静态属性
class MathUtils {
// 静态属性(ES2022)
static PI = 3.14159;
static version = '1.0.0';
// 静态方法
static add(a, b) {
return a + b;
}
static multiply(a, b) {
return a * b;
}
static getCircleArea(radius) {
return this.PI * radius * radius; // 使用静态属性
}
// 实例方法
calculate(operation, a, b) {
switch(operation) {
case 'add':
return MathUtils.add(a, b); // 调用静态方法
case 'multiply':
return MathUtils.multiply(a, b);
default:
return 0;
}
}
}
// 使用静态方法和属性
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.add(5, 3)); // 8
console.log(MathUtils.getCircleArea(5)); // 78.53975
// 静态方法不能通过实例调用
const utils = new MathUtils();
console.log(utils.calculate('add', 5, 3)); // 8 (实例方法)
// console.log(utils.add(5, 3)); // ❌ TypeError: utils.add is not a function// 🎉 静态方法的继承
class Animal {
static kingdom = 'Animalia';
static getKingdom() {
return this.kingdom;
}
static createRandom() {
const names = ['Buddy', 'Max', 'Charlie'];
const randomName = names[Math.floor(Math.random() * names.length)];
return new this(randomName);
}
}
class Dog extends Animal {
static species = 'Canis lupus';
constructor(name) {
super();
this.name = name;
}
static getSpecies() {
return this.species;
}
static createRandomDog() {
// 调用父类静态方法
return super.createRandom();
}
}
// 静态方法继承
console.log(Dog.getKingdom()); // Animalia (继承自Animal)
console.log(Dog.getSpecies()); // Canis lupus (Dog特有)
// 静态方法中的this指向当前类
const randomDog = Dog.createRandom(); // 创建Dog实例
console.log(randomDog instanceof Dog); // true
const anotherDog = Dog.createRandomDog(); // 使用super调用
console.log(anotherDog instanceof Dog); // true**私有字段是什么?**这是ES2022引入的类封装特性,使用#符号定义私有字段和私有方法。私有字段只能在类内部访问,提供了真正的封装性。
// 🎉 ES2022私有字段和私有方法
class BankAccount {
// 私有字段
#balance = 0;
#accountNumber;
#pin;
// 公共字段
accountHolder;
constructor(accountHolder, initialBalance, pin) {
this.accountHolder = accountHolder;
this.#balance = initialBalance;
this.#accountNumber = this.#generateAccountNumber();
this.#pin = pin;
}
// 私有方法
#generateAccountNumber() {
return Math.random().toString(36).substr(2, 9).toUpperCase();
}
#validatePin(inputPin) {
return this.#pin === inputPin;
}
// 公共方法
getBalance(pin) {
if (!this.#validatePin(pin)) {
throw new Error('Invalid PIN');
}
return this.#balance;
}
deposit(amount, pin) {
if (!this.#validatePin(pin)) {
throw new Error('Invalid PIN');
}
if (amount <= 0) {
throw new Error('Amount must be positive');
}
this.#balance += amount;
return this.#balance;
}
withdraw(amount, pin) {
if (!this.#validatePin(pin)) {
throw new Error('Invalid PIN');
}
if (amount <= 0) {
throw new Error('Amount must be positive');
}
if (amount > this.#balance) {
throw new Error('Insufficient funds');
}
this.#balance -= amount;
return this.#balance;
}
getAccountInfo(pin) {
if (!this.#validatePin(pin)) {
throw new Error('Invalid PIN');
}
return {
holder: this.accountHolder,
accountNumber: this.#accountNumber,
balance: this.#balance
};
}
}
// 使用私有字段的类
const account = new BankAccount('John Doe', 1000, '1234');
console.log(account.accountHolder); // John Doe (公共字段)
console.log(account.getBalance('1234')); // 1000 (通过公共方法访问)
// ❌ 无法直接访问私有字段
// console.log(account.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing class
// console.log(account.#pin); // SyntaxError: Private field '#pin' must be declared in an enclosing class
// ✅ 通过公共方法操作
account.deposit(500, '1234');
console.log(account.getBalance('1234')); // 1500
try {
account.withdraw(200, 'wrong'); // 错误的PIN
} catch (error) {
console.log(error.message); // Invalid PIN
}// 🎉 私有静态字段和方法
class DatabaseConnection {
// 私有静态字段
static #instances = [];
static #maxConnections = 5;
// 私有字段
#connectionId;
#isConnected = false;
constructor(host, port) {
if (DatabaseConnection.#instances.length >= DatabaseConnection.#maxConnections) {
throw new Error('Maximum connections reached');
}
this.host = host;
this.port = port;
this.#connectionId = DatabaseConnection.#generateId();
DatabaseConnection.#instances.push(this);
}
// 私有静态方法
static #generateId() {
return Math.random().toString(36).substr(2, 9);
}
// 公共静态方法
static getActiveConnections() {
return DatabaseConnection.#instances.length;
}
static getMaxConnections() {
return DatabaseConnection.#maxConnections;
}
// 公共方法
connect() {
this.#isConnected = true;
console.log(`Connected to ${this.host}:${this.port} (ID: ${this.#connectionId})`);
}
disconnect() {
this.#isConnected = false;
const index = DatabaseConnection.#instances.indexOf(this);
if (index > -1) {
DatabaseConnection.#instances.splice(index, 1);
}
console.log(`Disconnected from ${this.host}:${this.port}`);
}
isConnected() {
return this.#isConnected;
}
}
// 使用示例
const db1 = new DatabaseConnection('localhost', 5432);
const db2 = new DatabaseConnection('remote', 3306);
db1.connect();
db2.connect();
console.log(DatabaseConnection.getActiveConnections()); // 2
console.log(DatabaseConnection.getMaxConnections()); // 5
db1.disconnect();
console.log(DatabaseConnection.getActiveConnections()); // 1通过本节ES6 class语法的学习,你已经掌握:
"ES6 class语法让JavaScript面向对象编程更加现代化和直观,是现代前端开发的必备技能!"