static 块是 es2022 引入的类内同步初始化机制,用于在类定义求值时立即、仅执行一次地完成私有静态字段初始化、环境判断、全局注册等需类加载即确定的操作。

JavaScript 中的 static 块(静态块)是 ES2022 正式引入的语法,它在类定义被求值时**立即、同步、仅执行一次**,作用就是做类级别的初始化工作——不是为某个实例服务,而是为整个类本身打基础。
它解决什么问题?
以前想在类里做复杂初始化,比如条件判断、异常处理、注册全局管理器、初始化私有静态字段,只能靠“类外 IIFE”或“静态方法调用”,既不内聚又难维护。静态块把这类逻辑直接写进类体内部,语义清晰、权限可控、时机明确。
- 不能用普通静态字段赋值完成的逻辑(比如需要
if或try/catch) - 不想等到第一次实例化才触发的预加载操作(比如读配置、建连接池)
- 需要访问类私有静态成员(
#privateField),而外部代码无权访问
怎么写?基本语法很简单
在类体内直接写 static { ... },里面可以放任意合法的同步语句:
class ApiClient {
static #baseUrl;
static #timeout = 5000;
static {
const env = globalThis?.ENV ?? 'prod';
if (env === 'dev') {
ApiClient.#baseUrl = 'http://localhost:3000/api';
} else {
ApiClient.#baseUrl = 'https://api.example.com';
}
console.log(`API base URL set to: ${ApiClient.#baseUrl}`);
}
}
注意:块内可访问该类所有静态成员(含私有),但不能用 this(因为没实例)、也不能访问实例字段或方法。
它在类加载时具体做什么?
当模块执行到这个类定义语句时,JS 引擎会:
- 先解析类结构(包括静态字段、方法、私有成员)
- 然后按出现顺序逐个执行所有
static块(支持多个) - 执行中若抛错,整个类定义失败,后续依赖该类的代码会报
ReferenceError - 完成后,类就“准备就绪”,可被其他代码引用或实例化
这个时机比构造函数早得多——甚至早于任何 new Xxx() 调用,也早于模块内后续语句执行。
哪些事适合放在 static 块里?
核心原则:必须是“类一加载就得定下来”的事情,且不能异步。
- 校验静态配置是否合法(比如枚举值缺失、必填字段为空,直接
throw中断) - 初始化私有静态缓存或映射表(如
static #registry = new Map()后填充子类) - 向全局事件总线或 DI 容器注册当前类(如
EventBus.register('ApiClient', ApiClient)) - 设置环境相关常量(如上例中的
#baseUrl)
别在里面发网络请求、读文件、跑大循环——这些都会卡住模块加载,影响首屏或启动性能。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











