Ergonomic brand checks for Private Fields S4
中文标题:私有字段的人体工程学品牌检查
- 阶段: Stage 4
- 状态: 已完成
- ECMAScript 版本: ES2022
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案解决了在不抛出异常的情况下检查对象是否具有私有字段的问题,目前需要使用笨拙的 try/catch 模式。主要解决方案引入了 in 运算符来测试私有字段的存在性,例如 #brand in obj。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
私有字段的人体工程学品牌检查
EcmaScript 提案、规范和参考实现,用于提供无异常的品牌检查。
规范由 @ljharb 起草。
基于 https://github.com/tc39/ecma262/pull/1668/ 构建,等待类字段进入第 4 阶段并合并到更大的规范中。
该提案目前处于 流程 的第 4 阶段。
理由
私有字段内置了“品牌检查”,即如果你尝试在未安装该私有字段的对象上访问私有字段,它会抛出异常。
这很好!但是,为了真正保持私有字段的存在性,我经常需要检查对象是否具有私有字段,如果没有,则有一些回退行为(甚至可能抛出自定义异常,该异常的消息不会泄露我使用私有字段作为机制的事实)。
为此使用 try/catch 确实可行,但相当笨拙:
这对于 getter(可能抛出异常)来说也是一个问题:
所期望的是一个简单的解决方案,用于生成表示私有字段是否存在的布尔值,而不需要 try/catch 或异常。
解决方案:
in
最明显的解决方案是使用 in 关键字,如下所示:
这没有我所知的 ASI 风险;然而,它有一个重要的权衡:它永久地扼杀了私有字段简写的任何可能性。具体来说,这是因为如果 #brand(在前面的例子中)是 this.#brand 的简写,那么 (#brand) in obj 必须与 this.#brand in obj 相同,这意味着“this.#brand 的_值_是否在 obj 中?”,而不是“obj 是否具有私有字段 #brand?”。
被拒绝的解决方案:
try 语句
另一种替代方案是:
然而,这强烈暗示 try <expression> 将是一种通用语法,表示“如果它抛出异常,产生 false,否则产生 true”。那将是一个更大的提案,并且对于解决私有字段的具体问题来说可能有点过头了。
这将需要对花括号进行前瞻限制(这意味着 try 表达式不能是对象字面量,除非用括号括起来)。
规范
您可以查看 in 解决方案的规范,渲染为 HTML。