json.stringify 不走 proxy 拦截,因其是底层引擎行为,不触发 get、ownkeys 等 trap,直接读取自有可枚举属性原始值,忽略 getter、symbol 键、函数及不可枚举属性。

Proxy 本身无法直接拦截 JSON.stringify 这类序列化操作,因为 JSON 序列化不触发 get、ownKeys 等 trap,它只读取对象自有可枚举属性的值,且跳过函数、undefined、Symbol 键和循环引用。但可以通过组合策略间接控制序列化结果。
为什么 JSON.stringify 不走 Proxy 拦截?
JSON 序列化是底层引擎行为,它:
- 不调用
get—— 直接读取属性原始值(绕过代理逻辑) - 不调用
ownKeys或has—— 使用内部自有属性列表 - 忽略 getter、不可枚举属性、Symbol 键和 Proxy 特有行为
- 遇到函数、undefined、NaN、Infinity 会丢弃或转为 null
让动态属性/计算属性出现在 JSON 中
如果希望某些“虚拟属性”(如 proxy.fullName)被序列化,需显式将其转为真实属性:
- 在序列化前手动展开:用
Object.assign({}, proxy)或遍历 key 赋值到新对象 - 定义
toJSON方法(推荐):Proxy 的 target 或其原型上添加toJSON(),返回自定义 plain object - 示例:
target.toJSON = () => ({ ...target, fullName: `${target.firstName} ${target.lastName}` });
拦截并定制序列化流程
真正可控的方式是封装序列化调用,而非依赖原生行为:
- 重写全局
JSON.stringify(仅限开发/测试环境,慎用于生产) - 提供专用方法如
proxy.serialize(),内部调用Reflect.ownKeys(target)+Reflect.get()获取所有(包括动态)属性 - 配合
get+ownKeys+getOwnPropertyDescriptor构建完整属性视图,再递归处理嵌套 Proxy
避免序列化敏感或临时数据
可通过 toJSON 或封装方法过滤字段:
- 在
toJSON中剔除 token、loading 等非持久字段 - 利用
ownKeys返回精简键名列表,再结合get提取值 - 对值做预处理:自动字符串化 Date、忽略 Symbol、扁平化 Map/Set
不复杂但容易忽略:Proxy 的强大在于运行时访问控制,而序列化是快照行为——想让它“听话”,就得主动接管,而不是指望 trap 自动生效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











