从语法糖到引擎实现——JavaScript Class 完整指南(2025 版)
☕ 404 星球 · 前端晨间广播 | 2025-10-26
1️⃣ Gemini 3.0 全家桶凌晨发布
Google 正式推出 Gemini 3.0 Pro/Flash/Ultra,MoE 架构、万亿参数;配套 Gemini-CLI 可一键生成 React + TypeScript 项目骨架,官方称“原型到生产 5 分钟”,前端脚手架迎来“大模型原生”时代。
2️⃣ 川渝 Web 前端开发技术交流会今日开幕
重庆两江软件园现场议题:AI 低代码、鸿蒙原生开发、性能监控实战;设有“AI 应用创作大赛”与招聘专区,线上同步直播,免费报名即领周边。
3️⃣ Figma 正式收购 Payload CMS
设计到内容一站式工作流首次闭环:设计师在 Figma 即可调用 Payload GraphQL 端点,自动生成 TypeScript 类型安全的组件代码,开源承诺保持不变,插件市场预计 11 月上线 Beta。
4️⃣ CSS @scope 全平台通关
Firefox 132 Nightly 默认开启 @scope,至此 Chrome、Safari、Firefox 三大内核全部支持,组件级样式隔离无需 CSS Modules,2026 进候选标准。
5️⃣ Node.js 安全补丁紧急推送
10 月安全版本同时修复 2 个 HIGH 级漏洞(HTTP 走私 + DNS 重绑定),23.x、22.x、20.x LTS 同步获得更新,官方建议生产环境 24h 内升级。
— ☕️🌅 —
一、写在前面:为什么又要讲 Class?
ES6 发布已近十年,「Class 只是语法糖」这句话几乎成了面试口头禅。
但 2022 之后,ECMAScript 一口气塞进了「私有字段、静态初始化块、装饰器」三把大杀器,很多老教程明显过时。
今天这篇,就带你从「写代码」到「看引擎」,一次性把 Class 吃干抹净。
二、十分钟速通:Class 语法全景图
1. 最简洁的类
class Person {name = 'Anonymous'; // 实例字段#age = 0; // 私有字段(ES2022)constructor(name) {this.name = name;}greet() { // 实例方法console.log(`Hi, ${this.name}, age ${this.#age}`);}static species = 'Homo sapiens';static create(name) { // 静态方法return new this(name);}static { // 静态初始化块(ES2022)console.log('Person class loaded');}
}
2. 继承一条链
class Employee extends Person {#salary;constructor(name, salary) {super(name); // 必须在 this 之前this.#salary = salary;}greet() {super.greet(); // 调用父类实例方法console.log('And I am an employee');}static createIntern(name) {return super.create(name); // 调用父类静态方法}
}
3. 使用侧代码
const e = Employee.createIntern('Alex');
e.greet();
// 控制台:
// Person class loaded
// Hi, Alex, age 0
// And I am an employee
三、灵魂追问:Class 到底生成了什么?
1. 类 = 函数 + 原型
typeof Person // "function"
Person.prototype.constructor === Person // true
2. 继承 = 两条链
// 静态链
Employee.__proto__ === Person // true// 实例链
Object.getPrototypeOf(Employee.prototype) === Person.prototype // true
3. 私有字段的魔法
引擎在每次实例化时创建一个隐藏的 WeakMap,用「brand check」保证外部无法访问:
const p = new Person('Tom');
p.#age // SyntaxError: Private field '#age' must be declared in an enclosing class
四、实战踩坑合集
| 坑点 | 示例 | 正确姿势 |
|---|---|---|
| 提升 | new Foo(); class Foo{} | ReferenceError,类不会提升 |
| super 顺序 | 先 this 后 super | 必报错 |
| this 丢失 | const {greet} = employee; greet() | 用箭头函数或 bind |
| 私有字段被反射 | Reflect.ownKeys(obj) | 列表里永远找不到 #xxx |
| 静态块异步 | static { await fetch() } | 语法错误,静态块内部不能直接用 await(可用 IIFE) |
五、进阶玩法:装饰器 + Mixin + 高阶类
1. 装饰器(Stage-3)
@frozen
class API {@throttle(300)call() {}
}function frozen(Constructor) {Object.freeze(Constructor);Object.freeze(Constructor.prototype);
}
2. Mixin:组装更小的类
const Serializable = Sup => class extends Sup {toJSON() { return JSON.stringify(this); }
};class Model extends Serializable(Person) {}
3. 高阶类(HOC)
function withLog(Cls) {return class extends Cls {constructor(...a) {super(...a);console.log('New', Cls.name, this);}};
}
const Logged = withLog(Employee);
六、性能与内存小贴士
- 实例字段箭头函数
foo = () => {}每个实例一份闭包,方便但占内存;高并发场景慎用。 - 方法放原型
foo() {}全部实例共享,内存友好。 - 私有字段成本
引擎会分配额外存储空间,对百万级对象才有感觉,普通业务可忽略。
七、一张图总结(保存即可)
┌-------------------------┐
│ 类声明 │
│ constructor │
│ 实例方法 / 字段 │
│ 私有方法 / 字段 (#) │
│ 静态方法 / 字段 (static)│
│ 静态初始化块 (static{}) │
└------------┬------------┘│ extends▼
┌-------------------------┐
│ 子类 (两条链) │
│ 静态链:Child→Parent │
│ 原型链:Child.prototype│
│ →Parent.prototype│
└-------------------------┘
八、写在最后
Class 语法让 JavaScript 看起来更像“正统 OO”,但骨子里依旧是原型。
理解「prototype、super、静态链、私有字段」这四块基石,你就能在「写业务」和「读源码」之间游刃有余。
如果本文对你有帮助,点个 赞,我们评论区见!
