Class Static Block S4
中文标题:类静态初始化块
- 阶段: Stage 4
- 状态: 已完成
- ECMAScript 版本: ES2022
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案在类体中引入了静态初始化块,允许在类定义求值期间执行任意语句,从而在类内部实现 try/catch 逻辑和多字段初始化,并拥有对私有状态的特权访问。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
ECMAScript 类静态初始化块
类 static 块提供了一种机制,在类定义求值期间执行额外的静态初始化。
这并非旨在替代公共字段,因为它们为静态分析工具提供了有用信息,并且是装饰器的有效目标。相反,它旨在扩展现有用例,并支持该提案当前未处理的新用例。
状态
阶段: 4
提案发起人: Ron Buckton (@rbuckton)
有关该提案的详细状态,请参见下面的 TODO。
作者
- Ron Buckton (@rbuckton)
动机
当前关于静态字段和静态私有字段的提案提供了一种在 ClassDefinitionEvaluation 期间对类的静态部分进行逐字段初始化的机制,但有些情况不容易覆盖。例如,如果需要在初始化期间求值语句(如 try..catch),或从单个值设置两个字段,则必须在类定义之外执行该逻辑。
此外,在某些情况下,具有实例私有字段的类与在同一作用域中声明的另一个类或函数之间需要进行信息共享。
静态块提供了在类声明的上下文中求值语句的机会,并可特权访问私有状态(无论是实例私有还是静态私有):
与“私有声明”的关系
提案:https://github.com/tc39/proposal-private-declarations
“私有声明”提案也旨在解决两个类之间的特权访问问题,其做法是将私有名称从类声明中提升到封闭作用域中。虽然在这方面有一些重叠,但私有声明并不能解决多步静态初始化的问题,除非纯粹为了初始化而将私有名称暴露给外部作用域:
此外,私有声明暴露的私有名称可能允许对共享私有状态进行读写访问,而只读访问可能是更可取的。要使用私有声明解决此问题,需要额外的复杂性(尽管 static{} 也有类似的成本):
然而,从长远来看,这两个提案并不妨碍彼此同时使用:
先例
语法
语义
static {}初始化块创建一个新的词法作用域(例如,var、function和块级声明都限于该static {}初始化块内部。此词法作用域嵌套在类体的词法作用域中(授予该类实例私有状态的特权访问权限)。- 类在其类体中可以有任意数量的
static {}初始化块。 static {}初始化块按照文档顺序与静态字段初始化器交错求值。static {}初始化块不能有装饰器(相反,您会装饰类本身)。- 求值时,
static {}初始化块的this接收者是类的构造函数对象(与静态字段初始化器相同)。 - 在
static {}初始化块内引用arguments是语法错误。 - 在
static {}初始化块内包含 SuperCall(即super())是语法错误。 static {}初始化块可以包含 SuperProperty 引用,以访问或调用基类上可能已被包含static {}初始化块的派生类覆盖的静态成员。- 在调试器和异常跟踪中,
static {}初始化块应表示为独立的堆栈帧。
示例
参考
TODO
以下是推进 TC39 提案流程 各阶段所需的高级任务列表:
阶段 1 进入标准
阶段 2 进入标准
- 初始规范文本。
- 转译器支持(可选)。
- Babel
v7.12.0 - TypeScript
v4.4 beta(TypeScript 游乐场)
- Babel
阶段 3 进入标准
阶段 4 进入标准
有关阶段 4 标准的最新信息,请查看:#48
- 已为主要使用场景编写 Test262 验收测试,并合并。
- 两个通过验收测试的兼容实现:
- SpiderMonkey — 部分在 92 版本中通过标志 发布,在 93 版本中计划不带标志发布:

- V8 — 不带标志发布(至少从 9.4.146 开始):

- SpiderMonkey — 部分在 92 版本中通过标志 发布,在 93 版本中计划不带标志发布:
- 已将包含集成规范文本的拉取请求发送到 tc39/ecma262。
- ECMAScript 编辑已签署该拉取请求。