javascript类私有属性与方法唯一原生方式是#前缀语法(es2022/es13标准),仅类内可访问,支持字段、方法、getter/setter,必须顶层声明,不参与枚举或序列化。

JavaScript 中 Class 的私有属性与私有方法,从 ES2022(Node.js 16.0+ / 浏览器 Chrome 91+)起,原生支持使用 # 前缀语法,这是目前最标准、最可靠的方式。
用 # 号声明私有字段(属性和方法)
在类内部,以 # 开头的标识符即为私有成员,仅能在类的自身方法中访问,外部和子类都无法读取或调用。
- 私有属性必须在类体顶层声明(可带初始值),不能在 constructor 内动态添加
- 私有方法也以 # 开头,可被其他类方法调用,但不可被实例或子类访问
- 同一个类的不同实例之间,私有字段是彼此隔离的(符合直觉)
示例:
class Counter {
#count = 0; // 私有属性,支持初始化
#increment() { // 私有方法
this.#count++;
}
<p>get value() {
return this.#count;
}</p><p>tick() {
this.#increment(); // ✅ 允许:类内部调用
}
}</p><p>const c = new Counter();
c.tick();
console.log(c.value); // 1
// console.log(c.#count); // ❌ SyntaxError:非法访问
// c.#increment(); // ❌ 同样报错</p>注意:私有字段不参与 for...in / Object.keys() / JSON.stringify
私有字段完全不暴露在对象的可枚举属性中,也不会出现在序列化结果里,天然具备封装性。
-
Object.getOwnPropertyNames(c)和Reflect.ownKeys(c)也看不到#count - 这不同于下划线约定(如
_count),后者只是语义提示,实际仍可随意访问
兼容旧环境?慎用“闭包模拟”或 WeakMap 方案
若需支持 ES2022 之前环境(如 IE 或老版 Node),可借助闭包 + WeakMap 模拟私有状态,但复杂且有局限:
- WeakMap 键必须是对象,适合存储实例级私有数据;但无法定义私有方法(方法仍是公开的,只是内部用 WeakMap 查状态)
- 无法实现真正的私有方法封装,且调试困难、影响 tree-shaking
- 现代项目建议优先升级运行时,而非降级方案
继承中的私有成员不可访问
子类无法访问父类的 # 字段,哪怕同名也不共享作用域:
class Parent {
#x = 1;
getX() { return this.#x; }
}
class Child extends Parent {
tryAccess() {
// return this.#x; // ❌ 报错:#x 未在 Child 中定义
}
}
如需受控继承,应通过受保护的 getter/setter 或公开方法间接暴露必要能力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











