如何可靠地将JavaScript Proxy对象转换为标准对象?
问题解答
为什么JSON.parse(JSON.stringify(event.detail))有时仍显示Proxy对象?
这不是JSON.parse把字符串转成了Proxy,核心原因有两个:
浏览器控制台的实时特性:
浏览器控制台的console.log不会立即对对象做快照,而是在你展开面板时才读取对象的当前状态。如果event.detail或其嵌套对象在你展开控制台前被代码重新包装成Proxy,就会显示为Proxy。而直接console.log(JSON.stringify(...))输出的是静态字符串,不受后续对象变化影响,所以能看到原始数据。嵌套Proxy的序列化不彻底:
如果event.detail是顶层Proxy,但其内部嵌套了其他未正确处理序列化的Proxy对象,JSON.stringify可能只能序列化顶层Proxy的属性,而嵌套Proxy的属性访问被陷阱拦截,导致序列化后的字符串不完整。当你解析回来时,若后续代码又对这些嵌套对象做了代理,就会显示为Proxy。
如何稳定获取嵌入对象的副本?
推荐以下几种可靠方法:
使用
structuredCloneAPI:
这是浏览器原生的深度克隆API,能正确处理Proxy对象(只要Proxy的陷阱允许访问属性),还支持JSON方法无法处理的类型(如Date、Map、Set等):const copy = structuredClone(event.detail); console.log(copy);借助框架工具函数:
如果你在使用Vue、React等框架,它们通常提供了获取原始对象的工具:- Vue:用
toRaw()直接获取Proxy包装的原始对象:import { toRaw } from 'vue'; const rawObj = toRaw(event.detail); // 再对原始对象做深克隆 const copy = structuredClone(rawObj); - React(如使用MobX等Proxy状态库):参考对应库的API获取原始对象后再克隆。
- Vue:用
手动递归克隆:
写一个递归函数,手动遍历并提取Proxy的原始属性(需根据框架或Proxy实现调整,比如Vue的Proxy会带__v_raw属性指向原始对象):function deepCloneProxy(target) { if (typeof target !== 'object' || target === null) return target; // 尝试获取Proxy的原始对象,不同环境可能有不同标识 const raw = target.__v_raw || target; if (Array.isArray(raw)) { return raw.map(item => deepCloneProxy(item)); } const clone = {}; for (const key in raw) { if (raw.hasOwnProperty(key)) { clone[key] = deepCloneProxy(raw[key]); } } return clone; } const copy = deepCloneProxy(event.detail); console.log(copy);
内容的提问来源于stack exchange,提问作者Chuck
相关产品推荐
相关产品推荐

