私有字段(#field)在 JSON 序列化时完全不可见且被静默忽略,因其不属于对象属性,不参与枚举、Object.keys()、JSON.stringify() 等任何基于属性的操作,仅可通过显式定义的 toJSON() 方法手动暴露。

JavaScript 中私有字段(#field)在 JSON 序列化时完全不可见,会被静默忽略——既不报错,也不出现在结果中。
私有字段不会进入序列化流程
JSON.stringify() 只遍历对象的可枚举自身属性,而私有字段不属于属性(Property),它是类内部的词法绑定,不参与对象的属性枚举、for…in、Object.keys() 或 JSON 序列化过程。
- 即使私有字段已赋值,
JSON.stringify({})对实例调用,也不会包含它 - 私有字段不会触发 getter/setter,也不会被 toJSON() 方法自动捕获(除非你显式在 toJSON 中读取并返回)
- 它和 Symbol 属性类似:不是“被过滤”,而是根本不在属性遍历路径上
toJSON() 是唯一可控出口
若希望私有字段参与序列化,必须在类中手动定义 toJSON() 方法,并在其中显式读取私有字段值,返回一个普通对象:
class User {
#id;
constructor(id) { this.#id = id; }
toJSON() {
return { id: this.#id }; // 主动暴露
}
}
JSON.stringify(new User(123)); // '{"id":123}'
反序列化后无法自动恢复私有状态
JSON.parse() 得到的是 plain object,没有类构造信息,更无私有字段机制。即使原始 JSON 含有 "id": 123,也无法自动还原为带 #id 的实例。
立即学习“Java免费学习笔记(深入)”;
- 需手动用该数据新建实例:
new User(data.id) - 不能依赖 JSON 字符串“原样保存再还原”私有字段语义
- 私有字段本质是运行时封装,不是数据结构的一部分
与其它不可序列化值的本质区别
私有字段的“消失”不同于 undefined 或 function 的静默丢弃——后者是 stringify 的过滤行为;而私有字段压根不构成 stringify 的输入项。它属于语言级访问控制,而非序列化策略问题。
- 不支持
Object.getOwnPropertyNames()或Reflect.ownKeys()获取 - 不存在于
Object.assign()、结构赋值、展开运算符等任何基于属性的操作中 - 因此,所有基于属性反射的序列化方案(包括第三方库)均无法触及它


















