ES6 引入了 class 语法,提供了更清晰的面向对象编程方式。class 本质上是基于原型的语法糖。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}
const person = new Person('Alice', 25);
console.log(person.greet()); // "Hello, I'm Alice"
class Person {
constructor(name) {
this.name = name;
console.log('Person created');
}
}
const person = new Person('Alice'); // Person created
class Person {
constructor(name) {
this.name = name;
}
// 实例方法
greet() {
return `Hello, ${this.name}`;
}
// 静态方法
static create(name) {
return new Person(name);
}
}
const person = new Person('Alice');
person.greet(); // 'Hello, Alice'
Person.create('Bob'); // 使用静态方法
class MathUtils {
static add(a, b) {
return a + b;
}
static multiply(a, b) {
return a * b;
}
}
MathUtils.add(1, 2); // 3
MathUtils.multiply(2, 3); // 6
class Config {
static apiUrl = 'https://api.example.com';
static version = '1.0.0';
}
console.log(Config.apiUrl); // 'https://api.example.com'
class BankAccount {
#balance = 0; // 私有字段
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
// account.#balance; // SyntaxError: Private field
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
}
const person = new Person('Alice', 'Smith');
console.log(person.fullName); // 'Alice Smith'
person.fullName = 'Bob Jones';
console.log(person.firstName); // 'Bob'
使用 extends 关键字实现继承:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
speak() {
return `${this.name} barks`;
}
}
const dog = new Dog('Buddy', 'Golden Retriever');
console.log(dog.speak()); // 'Buddy barks'
console.log(dog.name); // 'Buddy'
super(...args)super.methodName()class Animal {
constructor(name) {
this.name = name;
}
move() {
return `${this.name} moves`;
}
}
class Bird extends Animal {
constructor(name, canFly) {
super(name);
this.canFly = canFly;
}
move() {
return this.canFly
? `${this.name} flies`
: super.move(); // 调用父类方法
}
}
const bird = new Bird('Eagle', true);
console.log(bird.move()); // 'Eagle flies'
// 命名类表达式
const Person = class NamedPerson {
constructor(name) {
this.name = name;
}
};
// 匿名类表达式
const Animal = class {
constructor(name) {
this.name = name;
}
};
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
return this;
}
}
const s1 = new Singleton();
const s2 = new Singleton();
console.log(s1 === s2); // true
class AnimalFactory {
static create(type, name) {
switch (type) {
case 'dog':
return new Dog(name);
case 'cat':
return new Cat(name);
default:
throw new Error('Unknown animal type');
}
}
}
const dog = AnimalFactory.create('dog', 'Buddy');
const Flyable = {
fly() {
return `${this.name} is flying`;
}
};
const Swimmable = {
swim() {
return `${this.name} is swimming`;
}
};
class Duck extends Animal {
constructor(name) {
super(name);
Object.assign(this, Flyable, Swimmable);
}
}
const duck = new Duck('Donald');
console.log(duck.fly()); // 'Donald is flying'
console.log(duck.swim()); // 'Donald is swimming'
class AbstractShape {
constructor() {
if (new.target === AbstractShape) {
throw new Error('Cannot instantiate abstract class');
}
}
getArea() {
throw new Error('Method must be implemented');
}
}
class Circle extends AbstractShape {
constructor(radius) {
super();
this.radius = radius;
}
getArea() {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.getArea()); // 78.54
// ES5 构造函数
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, ${this.name}`;
};
// ES6 类
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
const person = new Person('Alice'); // ReferenceError
class Person {
constructor(name) {
this.name = name;
}
}
class Person {
constructor(name) {
this.name = name; // 自动严格模式
}
}
class Person {
greet() {}
}
const person = new Person();
console.log(Object.keys(person)); // [] (方法不可枚举)
class Person {
constructor(name) {
this.name = name;
}
}
Person('Alice'); // TypeError: Class constructor cannot be invoked without 'new'
class Person {
constructor() {
Person = 'changed'; // TypeError: Assignment to constant variable
}
}
class Person {
// 公共字段
name = 'Unknown';
age = 0;
// 私有字段
#privateField = 'private';
// 静态公共字段
static version = '1.0.0';
// 静态私有字段
static #privateStaticField = 'private static';
constructor(name) {
this.name = name;
}
}
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
// 等价于
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, ${this.name}`;
};
// 验证
const person = new Person('Alice');
console.log(person.__proto__ === Person.prototype); // true
console.log(person instanceof Person); // true