私有字段(#)不会出现在 json.stringify 结果中,因其仅类内可访问、不作为对象属性存在,遍历和序列化均不可见;需通过 tojson() 等显式方法手动导出。

私有字段(#)在 JavaScript 中是真正的私有成员,JSON.stringify() 默认完全忽略它们——既不报错,也不输出,就像它们不存在一样。
为什么 # 字段不会出现在 JSON.stringify 结果中?
因为 # 字段仅在类实例内部可访问,不暴露为对象自身的可枚举/不可枚举属性,也不在 Object.keys()、for...in 或 JSON.stringify() 的遍历范围内。它本质上不是“属性”,而是一种语法级的封装机制。
想让私有字段参与序列化?得手动处理
不能靠默认行为,必须显式提取并注入到可序列化的结构中。常见做法:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 在类中提供一个
toJSON()方法,返回包含私有字段值的对象(注意:这不是“暴露私有性”,而是主动控制序列化逻辑) - 用 getter 暴露只读计算值,并在
toJSON()中引用它 - 避免直接序列化实例,改用专门的导出方法(如
exportData()),返回干净 plain object
例如:
class User {
#name;
#age;
<p>constructor(name, age) {
this.#name = name;
this.#age = age;
}</p><p>// ✅ 控制 JSON.stringify 行为
toJSON() {
return {
name: this.#name,
age: this.#age,
// 其他需要序列化的字段...
};
}
}</p><p>const user = new User("Alice", 30);
console.log(JSON.stringify(user)); // {"name":"Alice","age":30}</p>别踩坑:Proxy / 自定义序列化不能绕过 # 的限制
即使你用 Proxy 拦截 get,也无法从外部读取 #name——语法层面禁止。任何试图通过 this['#name']、Reflect.get() 或遍历方式访问私有字段的操作都会抛出 SyntaxError 或 TypeError。所以序列化逻辑必须写在类内部,且依赖已有的公开接口(如 getter 或 toJSON)。
替代方案:用 WeakMap 模拟私有,但需谨慎
如果对私有性的要求没那么严格(比如只是不想被枚举),可用 WeakMap 存储“伪私有”数据,并在 toJSON() 中读取。不过这失去语法级保护,且增加内存管理复杂度,一般不推荐只为 JSON 序列化而退化设计。










