私有成员是es2022正式引入的原生语法,以#开头的字段(属性、方法等)仅类内部可访问,外部、子类及反射api均不可探测或调用,由语言强制保障真正私有性。

JavaScript 类中用 # 修饰符定义的私有属性和方法,是 ES2022(ES13)正式引入的原生语法,它提供了真正意义上的访问隔离——不是靠约定、也不是靠运行时技巧,而是由语言本身强制保障。
什么是 # 私有成员?
以 # 开头的字段(包括属性、方法、getter/setter、静态成员),只能在声明它的类内部被访问。外部代码、子类、甚至通过 Object.keys 或 for...in 都无法探测或调用它们。
-
this.#name可在构造函数、实例方法、私有方法中自由使用 -
obj.#name在类外部直接写会触发SyntaxError - 子类无法继承
#成员,也无权访问父类的#字段
# 修饰符的写法与限制
私有成员必须在类体中显式声明,不能动态添加,也不能在类外补定义。
- 必须写在
class内部:如#count = 0、#doWork() {} - 支持静态私有成员:
static #token = 'abc',仅能被静态方法访问 - 不支持解构赋值获取私有字段:
const { #id } = instance是语法错误 - 不支持私有字段作为
super调用目标:super.#method()不合法
为什么推荐优先使用 # 而非旧方案?
相比下划线约定、Symbol、WeakMap 或闭包,# 方案更简洁、安全、高效。
- 下划线(
_name)只是命名习惯,完全不阻止访问 -
Symbol属性仍可通过Object.getOwnPropertySymbols()暴露 -
WeakMap带来额外内存开销,且访问性能比#低约 30% - V8 引擎对
#字段做了专门优化,访问速度更快,类型工具(如 TypeScript)也能精准识别
实际使用注意事项
虽然语法简单,但几个细节容易踩坑:
- 私有字段必须初始化或在构造函数中赋值,否则为
undefined(不像普通属性可延迟设置) - 不能在私有方法中通过字符串拼接绕过检查,如
this['#' + 'name']依然报错 - TypeScript 4.9+ 完全支持
#语法,但需确保target设为ES2022或更高 - Node.js 16.0+、Chrome 91+、Firefox 94+ 等主流环境均已稳定支持
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











