es6 class 的静态初始化块(static{})是 es2022 引入的同步初始化钩子,用于类定义完成后、实例化前一次性执行依赖计算、校验或跨静态成员协作等逻辑,支持多次声明、按序执行、异常中断初始化,并在继承中按父类先、子类后顺序运行。

ES6 Class 的静态初始化块(static{})是 ES2022 正式引入的特性,用来在类定义完成、但尚未被实例化时,**一次性执行同步初始化逻辑**。它不是“加载类”的手段,而是类就绪后立即运行的“初始化钩子”,专为处理静态元数据而设计。
什么时候该用 static 块?
当你需要初始化静态属性,且这个初始化过程涉及依赖计算、条件判断、错误校验或跨静态成员协作时,static 块比分散赋值更安全、清晰:
- 多个静态属性之间有先后依赖(比如
config要基于DEFAULTS深拷贝再修改) - 需要统一做存在性检查或格式校验(如确保必填字段已声明)
- 要注册到全局注册表、装饰器映射表或枚举查表结构中
- 想避免把初始化逻辑写在类外部,破坏封装性
基本写法和执行规则
static 块写在类体内部,用 static{} 包裹,可出现多次,按书写顺序依次执行:
示例:
class ApiClient {
static BASE_URL = 'https://api.example.com';
static TIMEOUT = 5000;
static headers = null;
static {
// 第一个块:构建默认 headers
this.headers = { 'Content-Type': 'application/json' };
}
static {
// 第二个块:基于 headers 和 BASE_URL 做校验
if (!this.BASE_URL.startsWith('https://')) {
throw new Error('BASE_URL must be HTTPS');
}
}
}
注意:
– 它只执行一次,且在任何 new ApiClient() 之前;
– 可以访问本类已声明的静态属性和方法,也能调用外部函数;
– 支持 try/catch,异常会中断类初始化,后续引用直接报错(这是优势,能早期暴露配置问题)。
在继承中怎么配合使用?
父类的 static 块先执行,子类的后执行——这个顺序天然支持分层元数据构建:
- 父类定义通用 schema 结构(如
id、createdAt) - 子类在自己的 static 块中扩展专属字段,并复用父类结果
- 无需手动合并对象,靠执行时序和
this.schema引用即可
示例:
class Model {
static schema = {};
static {
this.schema.id = { type: 'number', autoIncrement: true };
}
}
class User extends Model {
static {
// 自动继承父类 schema(因为父块已执行)
this.schema = { ...Model.schema };
this.schema.name = { type: 'string', required: true };
this.schema.role = { enum: ['admin', 'user'] };
}
}
哪些事绝对不能做?
static 块本质是同步、确定性、无副作用的初始化阶段。以下操作会引发问题或违反设计意图:
- 调用
fetch、setTimeout等异步 API(会立即返回undefined,无法等待) - 读取尚未声明的父类静态属性(除非确认其 static 块已执行)
- 修改外部可变状态(如全局变量、DOM),应保持纯初始化语义
- 忽略关键字段校验,导致运行时才发现缺失(建议用
if (!this.schema.xxx) throw主动防护) - 忘记冻结最终对象(
Object.freeze(this.schema)),防止后续被意外篡改











