Json <-> Object 序列化与反序列化

本文汇总了关于使用 LiftWeb 框架进行 JSON 构造与解析的相关资源与讨论链接,涉及如何在 Scala 和 LiftWeb 中操作 JSON 数据的具体方法。
综合了一下:

http://www.assembla.com/wiki/show/liftweb/JSON_Support

https://groups.google.com/group/liftweb/browse_thread/thread/d38090d804d902a3/7d7b55c4a63b2580?lnk=gst&q=json&hl=fi#7d7b55c4a63b2580

http://stackoverflow.com/questions/927983/how-can-i-construct-and-parse-a-json-string-in-scala-lift
这个错误: ``` Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'vnode' -> object with constructor 'Object' --- property 'component' closes the circle at JSON.stringify (<anonymous>) ``` 是 JavaScript 中常见的 **“循环引用”** 错误。当你尝试使用 `JSON.stringify()` 序列化一个包含**循环引用(circular reference)**的对象时,就会抛出此错误。 --- ### 🔍 问题原因 JavaScript 的 `JSON.stringify()` **不支持序列化包含循环引用的对象**。 例如: ```js const obj = {}; obj.self = obj; JSON.stringify(obj); // 报错:Converting circular structure to JSON ``` 在 Vue 或 React 等框架中,组件实例(如 `this`)、`vnode`、`refs` 等对象通常会互相引用,形成循环结构: ```js component.vnode.component === component // 循环引用! ``` 所以如果你尝试打印或序列化整个组件实例,比如: ```js console.log(JSON.stringify(this)); ``` 就会触发该错误。 --- ### ✅ 解决方案 #### ✅ 方案 1:使用安全的字符串化函数(推荐) 使用一个能处理循环引用的 `stringify` 函数,比如自定义递归检测,或使用第三方库。 ##### 方法 1.1:自定义 `safeStringify` ```js function safeStringify(obj, replacer = null, space = 2) { const seen = new WeakSet(); return JSON.stringify(obj, (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return "[Circular]"; } seen.add(value); } // 可选:过滤掉不需要的属性,如 vnode、_vnode 等 if (key === 'vnode' || key === '_vnode' || key === '$vnode') { return undefined; } return replacer ? replacer(key, value) : value; }, space); } // 使用示例 console.log(safeStringify(componentInstance)); ``` > 这个函数通过 `WeakSet` 记录已访问的对象,避免重复序列化导致的循环错误,并将循环引用替换为 `[Circular]`。 --- #### ✅ 方案 2:只序列化需要的数据(最佳实践) 不要序列化整个组件实例,而是提取你需要的部分。 ```js console.log( JSON.stringify({ props: this.$props, data: this.$data, name: this.$options.name }, null, 2) ); ``` 或者对于 Vue 3: ```js console.log( JSON.stringify({ props: this.props, data: this.data }, null, 2) ); ``` --- #### ✅ 方案 3:使用第三方库(如 `flatted`, `circular-json`, `fast-safe-stringify`) 安装: ```bash npm install flatted ``` 使用: ```js import { stringify } from 'flatted'; const circularObj = { name: "test" }; circularObj.self = circularObj; console.log(stringify(circularObj)); // 输出: [{"name":"test"},"^0.self"] ``` > `flatted` 可以安全地序列化反序列化循环结构。 --- #### ✅ 方案 4:开发调试时用 `console.log` 而非 `JSON.stringify` 浏览器的 `console.log()` 可以处理循环引用,不会报错: ```js console.log("Component:", this); // 安全 // ❌ 不要这样做: // console.log("Component:", JSON.stringify(this)); ``` --- ### 🛠️ 常见场景举例(Vue) ```js // ❌ 危险:可能包含 vnode -> component -> vnode 循环 JSON.stringify(this); // ✅ 安全做法 JSON.stringify({ props: this.$props, data: this.$data, computed: { count: this.count // 手动提取计算属性 } }); ``` --- ### 总结 | 方法 | 是否推荐 | 说明 | |------|----------|------| | 自定义 `safeStringify` | ✅ 推荐 | 控制力强,轻量 | | 提取有用字段再序列化 | ✅✅ 最佳实践 | 避免不必要的数据暴露 | | 使用 `flatted` / `fast-safe-stringify` | ✅ | 功能完整,适合复杂结构 | | 直接 `JSON.stringify(this)` | ❌ 禁止 | 必然出错 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值