javascript中以#开头的字段是语法层面的私有标识符,必须在类体顶层显式声明,静态确定作用域,不参与属性查找、枚举或反射,仅限声明类内部字面量访问。

JavaScript 中以 # 开头的字段名不是字符串前缀,而是语法层面的私有标识符,必须在类体顶层显式写出、静态确定,引擎在解析阶段就锁定其作用域和访问边界。
# 是词法标识符的一部分,不是运行时字符串
带 # 的名字(如 #id)是一个整体标识符,不是普通属性名加前缀。它不参与属性查找、枚举或反射,也不对应对象上的真实键名。写 this.#id 是合法访问;写 this["#id"] 或 obj.#id(外部)会直接报 SyntaxError,因为解析器根本不把它当作可动态访问的属性。
- #id 和 "id" 完全无关,二者在语法树中属于不同节点类型
- 不能用模板字符串、变量拼接或计算属性名生成私有字段名,例如
this[#key]或#[name]都非法 - 所有对 # 字段的引用,都必须在源码中以字面量形式明确写出
必须在 class 主体中声明,不可延迟或动态添加
私有字段只能出现在 class 大括号内部的顶层位置,且需显式声明。它不是实例创建后才挂载的属性,而是类定义时就固化下来的内部槽位。
- ✅ 正确:
class A { #x = 0; #y; }(声明即存在,可初始化也可留空) - ❌ 错误:
constructor() { this.#z = 1; }(未在类体中声明,语法错误) - ❌ 危险:
if (cond) this.#flag = true;(可能未声明就赋值,运行时报错)
作用域严格绑定到声明类,不随继承或实例传递
# 字段的作用域是词法作用域,只属于定义它的那个 class。子类、同类型其他实例、甚至同一类的静态方法(若未显式声明为静态私有字段)都无法共享或访问。
- 子类中写
super.#data或this.#data都会报错,父类私有字段对其完全不可见 - 同一类的两个实例 a 和 b,
a.#x和b.#x彼此隔离,a 无法读取 b 的 #x - 静态私有字段需显式声明为
static #count = 0;,否则实例方法里的this.#x永远指向实例私有槽位
不参与任何标准属性操作,彻底隐身于反射体系
私有字段在语言设计上被排除在所有属性相关 API 之外,既不暴露给开发者,也不被序列化或遍历逻辑捕获。
-
Object.keys(obj)、for...in、JSON.stringify(obj)均看不到它 -
Reflect.ownKeys(obj)和Object.getOwnPropertyNames(obj)返回空数组 -
"#x" in obj返回false,obj.hasOwnProperty("#x")也返回false
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











