author: 专注前端开发,分享JavaScript干货
title: JavaScript高级④|类(class)与面向对象,ES6现代写法
update: 2026-04-28
tags: JavaScript,class,面向对象,继承,静态方法,私有属性,前端进阶

作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:有JS基础,想用现代语法写面向对象程序的开发者


前言:class是语法糖

ES6的 class 本质上还是基于原型的继承,只是提供了更清晰的语法。

会用class,才能看懂现代前端框架的源码。


一、class基本语法

// ES5写法(原型方式)
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayHi = function() {
    console.log(`你好,我是${this.name}${this.age}`);
};
Person.prototype.introduce = function() {
    return `我叫${this.name}`;
};

// ES6 class写法(语法糖)
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    sayHi() {
        console.log(`你好,我是${this.name}${this.age}`);
    }

    introduce() {
        return `我叫${this.name}`;
    }
}

// 使用
const p = new Person("张三", 25);
p.sayHi(); // "你好,我是张三,25岁"
console.log(p.introduce()); // "我叫张三"

二、继承(extends + super)

class Animal {
    constructor(name) {
        this.name = name;
    }

    eat() {
        console.log(`${this.name}在吃东西`);
    }

    static info() {
        console.log("这是一个动物类");
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 调用父类构造函数(必须先调用)
        this.breed = breed;
    }

    bark() {
        console.log(`${this.name}在汪汪叫`);
    }

    // 方法重写
    eat() {
        super.eat(); // 调用父类方法
        console.log("狗狗吃得很香");
    }
}

const dog = new Dog("旺财", "金毛");
dog.eat();  // "旺财在吃东西" + "狗狗吃得很香"
dog.bark(); // "旺财在汪汪叫"
Dog.info();  // "这是一个动物类"(静态方法)

三、静态方法(static)

class MathUtils {
    // 静态方法:属于类,不属于实例
    static add(a, b) {
        return a + b;
    }

    static multiply(a, b) {
        return a * b;
    }

    // 实例方法
    sum(...numbers) {
        return numbers.reduce((a, b) => a + b, 0);
    }
}

// 调用静态方法
console.log(MathUtils.add(1, 2)); // 3
console.log(MathUtils.multiply(3, 4)); // 12

// 实例方法需要new
const utils = new MathUtils();
console.log(utils.sum(1, 2, 3)); // 6

// 静态属性(ES2022+)
class Config {
    static API_URL = "https://api.example.com";
    static TIMEOUT = 5000;
}
console.log(Config.API_URL); // "https://api.example.com"

四、私有属性和方法(ES2022+)

class User {
    // 公有字段(ES2022+)
    name = "默认名字";

    // 私有字段(#开头,外部无法访问)
    #password = "";
    #salary = 0;

    constructor(name, password) {
        this.name = name;
        this.#password = password;
    }

    // 公有方法
    changePassword(oldPwd, newPwd) {
        if (this.#verifyPassword(oldPwd)) {
            this.#password = newPwd;
            return true;
        }
        return false;
    }

    // 私有方法
    #verifyPassword(pwd) {
        return pwd === this.#password;
    }

    // getter(访问器)
    get info() {
        return `用户:${this.name}`;
    }

    // setter
    set salary(value) {
        if (value > 0) {
            this.#salary = value;
        }
    }

    get salary() {
        return this.#salary;
    }
}

const user = new User("张三", "123456");
console.log(user.name);      // "张三"(公有)
// console.log(user.#password); // ❌ SyntaxError
user.salary = 10000;
console.log(user.salary);    // 10000
console.log(user.info);      // "用户:张三"

五、抽象类模式(模拟)

// JS没有原生的抽象类,可以用抛出错误模拟
class Shape {
    constructor() {
        if (new.target === Shape) {
            throw new Error("不能实例化抽象类");
        }
    }

    // 抽象方法(子类必须实现)
    area() {
        throw new Error("子类必须实现area方法");
    }
}

class Circle extends Shape {
    constructor(radius) {
        super();
        this.radius = radius;
    }

    area() {
        return Math.PI * this.radius ** 2;
    }
}

// const s = new Shape(); // ❌ 报错
const c = new Circle(5);
console.log(c.area()); // 78.5398...

六、实战:数据模型封装

class Product {
    static #nextId = 1;

    constructor(name, price) {
        this.id = Product.#nextId++;
        this.name = name;
        this.price = price;
        this.createdAt = new Date();
    }

    // 折扣价
    get discountedPrice() {
        return this.price * 0.8;
    }

    // 格式化输出
    toString() {
        return `${this.name}(¥${this.price}`;
    }

    // 静态方法:批量创建
    static createMany(products) {
        return products.map(p => new Product(p.name, p.price));
    }
}

// 使用
const p1 = new Product("手机", 3000);
const p2 = new Product("耳机", 500);

console.log(p1.toString()); // "手机(¥3000)"
console.log(p1.discountedPrice); // 2400

const products = Product.createMany([
    { name: "电脑", price: 8000 },
    { name: "平板", price: 3000 }
]);
console.log(products.length); // 2

七、知识卡

概念 说明
class 定义类
constructor 构造函数
extends 继承
super() 调用父类构造函数/方法
static 静态方法/属性
#field 私有字段(ES2022+)
get / set 访问器

八、课后作业

  1. 用class实现一个 Queue(队列),有 enqueuedequeuefrontsize 方法
  2. 创建一个 BankAccount 类,私有字段 #balance,提供 depositwithdrawgetBalance 方法
  3. 用继承实现:BaseModel 基类有 savetoJSON 方法,UserModel 继承它并添加 fullName 属性

有问题欢迎评论区留言,大家一起讨论!


标签:JavaScript | class | 面向对象 | 继承 | 静态方法 | 私有属性 | 前端进阶

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐