Vue开发学习笔记:JSON.stringify(object)避免对象的循环引用报错

本文介绍如何使用JSON.stringify()方法,并通过传递一个函数作为第二个参数来避免因对象间存在循环引用而导致的错误。此方法可以确保数据正确转换为JSON字符串。

学习自:https://www.javaroad.cn/questions/146261

1.JSON.stringify()第二个参数使用函数解除转换对象的循环引用否则会报错Uncaught TypeError: Converting circular structure to JSON

var cache=[];
// var tem1=JSON.stringify(dataItem);
//JSON.stringify()第二个参数使用函数解除转换对象的循环引用否则会报错
//Uncaught TypeError: Converting circular structure to JSON
var jsonStr2=JSON.stringify(dataItem,function (key,value) { 
  if(typeof value==="object"&& value!==null&&key!==''){
	if(cache.indexOf(value)!== -1){
	  return;
	}
	cache.push(value);
  }else {
      return value;
  }
  
}) ;
cache=null;//清空变量,便于垃圾回收机制回收

注:函数中的逻辑根据自己需求写

### VueJSON.parse(JSON.stringify(obj))对象仍有 `__ob__` 属性导致取值报错的原因 在 Vue.js 的响应式机制中,Vue 会对数据对象进行劫持(通过 `Object.defineProperty` 或 `Proxy`),以实现对数据的监听和更新。这种劫持会在每个响应式对象上添加一个名为 `__ob__` 的属性,用于标识该对象已被 Vue 的响应式系统接管[^1]。 当使用 `JSON.stringify` 对对象进行序列化时,`__ob__` 属性会被忽略,因为它是一个不可枚举的属性。然而,在反序列化过程中(即调用 `JSON.parse`),生成的新对象并不会保留 `__ob__` 属性,因此它不再是 Vue 的响应式对象[^4]。 如果在 Vue 环境下直接操作这个新对象,可能会导致以下问题: - 新对象未被 Vue 响应式系统接管,因此无法触发视图更新。 - 如果尝试将新对象重新赋值给 Vue 实例中的某个响应式属性,Vue 可能会因为检测到非响应式对象而抛出错误或警告。 #### 解决方案 为了确保深拷贝后的对象能够继续被 Vue 的响应式系统管理,可以采取以下方法: 1. **手动将深拷贝后的对象转换为响应式对象** 使用 Vue 提供的 `Vue.set` 或 `this.$set` 方法,将深拷贝后的对象重新设置为响应式对象。例如: ```javascript let deepCopiedObj = JSON.parse(JSON.stringify(originalObj)); this.$set(this, 'targetProperty', deepCopiedObj); ``` 2. **避免直接深拷贝 Vue 响应式对象** 如果需要操作的对象Vue 的响应式对象,建议先将其从 Vue 响应式系统中解耦再进行深拷贝。可以通过访问原始数据的方式实现: ```javascript let rawObj = Object.assign({}, originalObj); // 获取原始数据 let deepCopiedObj = JSON.parse(JSON.stringify(rawObj)); ``` 3. **使用 Vue 的 `$data` 属性** 如果目标对象Vue 实例的 `data` 属性之一,可以直接操作 `$data` 对象,而不是直接操作响应式对象。例如: ```javascript let deepCopiedData = JSON.parse(JSON.stringify(this.$data)); ``` 4. **考虑其他深拷贝方法** 由于 `JSON.parse(JSON.stringify(obj))` 存在局限性(如无法处理函数、`undefined`、`Symbol` 等特殊值),可以使用第三方库(如 Lodash 的 `cloneDeep` 方法)来实现更全面的深拷贝[^3]: ```javascript import _ from 'lodash'; let deepCopiedObj = _.cloneDeep(originalObj); ``` #### 示例代码 以下是一个完整的示例,展示如何正确处理 Vue 响应式对象的深拷贝问题: ```javascript let originalObj = { a: 1, b: { c: 2 }, d: undefined, e: null, f: () => {} }; // 深拷贝对象 let deepCopiedObj = JSON.parse(JSON.stringify(originalObj)); // 手动将深拷贝后的对象设置为响应式 this.$set(this, 'newProperty', deepCopiedObj); // 或者使用 Lodash 的 cloneDeep 方法 import _ from 'lodash'; let deepCopiedObjWithLodash = _.cloneDeep(originalObj); ``` ### 注意事项 - 如果对象中包含循环引用,`JSON.stringify` 会抛出错误。需要提前处理循环引用问题。 - 如果对象中包含函数、`undefined` 或 `Symbol` 类型的值,这些值会在深拷贝过程中丢失[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值