TypeScript编译器何时使用WeakMap实现ECMAScript私有字段?
TypeScript 使用 WeakMap 模拟私有字段的场景区分
会采用 WeakMap 实现的情况
- 当使用 TypeScript 专属的
private修饰符(比如class User { private name: string }),且编译目标(tsconfig.json里的target)设为 ES2021 或更低版本时,编译器会用 WeakMap 来模拟私有字段的运行时隔离效果。- 具体做法是:生成一个外部无法访问的 WeakMap,用类实例作为键,私有属性的集合作为值。这样外部代码拿不到这个 WeakMap,就没法直接访问或修改私有属性,以此对齐 ES 原生私有字段的私有性。
- 开启
useDefineForClassFields配置并搭配低版本编译目标时,类的私有成员也会用 WeakMap 实现,来贴合 ES 类字段的规范行为。
不会采用 WeakMap 实现的情况
- 编译目标设为 ES2022 及更高版本时:
- 不管是用 TypeScript 的
private修饰符,还是直接写 ES 原生私有字段(#name),编译器都会输出原生的#私有字段语法,不需要 WeakMap 做兼容。
- 不管是用 TypeScript 的
- 使用
protected修饰符时:编译器不会用 WeakMap,而是转成普通对象属性(仅靠编译时检查限制访问),因为protected允许子类访问,WeakMap 的完全隔离逻辑不适用。 - 用
declare声明的私有成员:只做编译时的类型检查,不会生成任何运行时代码,自然也和 WeakMap 无关。
内容的提问来源于stack exchange,提问作者starball
相关产品推荐
相关产品推荐

