JSON.stringify报cyclic object value错误

本文介绍了解决JSON.stringify处理循环引用对象的问题,提供了两种方法:一是通过自定义序列化函数跟踪已遍历的对象;二是创建新对象避免引用循环。
obj = { x:"a", y: "b" };
obj.child = obj;
 
try{
    json = JSON.stringify(obj);
    alert(json)
}catch(e){
    alert(e);
}


如果调用上述代码,汇报JSON.stringify报cyclic object value错误,
而在程序开发的过程中也会出现意外的结果,
为了解决这个问题有两种办法
第一种


obj = { x:"a", y: "b" };
obj.child = obj;
 
alert(print(obj));
 
function print(obj){
    try{
        var seen = [];
        json = JSON.stringify(obj, function(key, val) {
           if (typeof val == "object") {
                if (seen.indexOf(val) >= 0) return;
                seen.push(val)
            }
            return val;
        });
        return json;
    }catch(e){
        return e;
    }
}


第二种
如果非想实现这种结果,那么拷贝原来的对象到新的对象中就行了
obj = { x:"a", y: "b" };
var newobj = {};
newobj.x = obj.x;
newobj.y = obj.y;
obj.child = newob;


                
### 性能 - **JSON.parse(JSON.stringify())**:该方法会先将 JavaScript 对象序列化为 JSON 字符串,再将字符串反序列化为新对象。此过程涉及两次转换,性能开销较大,尤其是处理大型复杂对象时,序列化和反序列化操作会消耗较多时间和内存。例如,对象中包含大量嵌套层级或大量属性时,转换速度会明显变慢。 - **cloneDeep**:通常是 Lodash 库中的深拷贝函数,它采用递归遍历对象的方式进行深拷贝。在处理复杂对象时,避免了序列化和反序列化的过程,性能相对较好。不过,如果对象嵌套层级过深,递归调用也会带来一定的性能损耗,但总体上比 JSON 转换方式更高效。 ### 使用场景 - **JSON.parse(JSON.stringify())**:适用于对象结构简单,不包含特殊属性(如函数、正则表达式、日期对象等)的情况。因为 JSON 格式有一定限制,无法处理这些特殊属性,若对象包含这些属性,转换过程中会丢失信息。例如,简单的配置对象、数据对象等可以使用此方法进行深拷贝。 - **cloneDeep**:适用于处理复杂对象,尤其是包含特殊属性(如函数、正则表达式、日期对象等)的情况。它能完整保留对象的所有属性和结构,确保深拷贝的准确性。例如,在处理包含方法的对象、具有复杂嵌套结构的对象时,cloneDeep 是更好的选择。 ### 区别 - **处理特殊属性**:JSON.parse(JSON.stringify()) 无法处理函数、正则表达式、日期对象等特殊属性,这些属性在转换过程中会被忽略或转换为不期望的结果。例如,函数会被忽略,日期对象会被转换为字符串。而 cloneDeep 可以正确处理这些特殊属性,保持对象的完整性。 - **错误处理**:JSON.parse(JSON.stringify()) 在对象包含无法序列化的属性时会抛出错误,导致深拷贝失败。而 cloneDeep 通常能更优雅地处理各种对象,避免因特殊属性而导致的错误。 以下是简单的代码示例: ```javascript const _ = require('lodash'); const searchMenuOptions = { value: { name: 'John', age: 30, sayHello: function() { console.log('Hello!'); } } }; // 使用 JSON.parse(JSON.stringify()) 进行深拷贝 const jsonClone = JSON.parse(JSON.stringify(searchMenuOptions.value)); console.log(jsonClone.sayHello); // undefined,函数丢失 // 使用 cloneDeep 进行深拷贝 const deepClone = _.cloneDeep(searchMenuOptions.value); console.log(deepClone.sayHello); // [Function: sayHello],函数保留 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值