JSON.stringify循环引用问题, structuredClone 深拷贝简介

一、JSON.parse(JSON.stringify(obj))实现深拷贝

前端使用到对象的深度复制通常会简单的使用JSON.parse(JSON.stringify(obj))实现 (浅表复制会用Array.from、Object.assign、Object.create静态方法实现),但在对象存在循环引用的情况下(比如:树结构中子对象存在parent属性存放父对象引用的情况)只是使用JSON.stringify(obj)会导致 “​TypeError: Converting circular structure to JSON​” 的循环引用错误: 

 这种情况可以利用JSON.stringify的可选参数“replacer”来解决问题

JSON.stringify 语法

JSON.stringify(value[, replacer [, space]])

 相关知识点: toJSON 方法

以下解决方法是传递函数作为“replacer”参数,过滤掉“_parent”属性(还有一种更简单的方式是传递“不包含_parent属性名,只包含所需要属性的名字的字符串数组”作为“replacer”参数即可轻松解决上面的错误):

以上代码中,this.MilestoneTrees是一个树状结构的数组,其中子结节中的“_parent”属性存放着对父节点的引用,这种情况直接只用“JSON.stringify(this.MilestoneTrees)”会导致文中开头所示的错误

  

还有一种解决方法,见以下文章,原理也是一样的,全文如下:

https://blog.51cto.com/u_15311558/5758502

在使用JSON.stringify方法去转化成字符串,会报错​​TypeError: Converting circular structure to JSON​​
原因: 对象中有对自身的循环引用;

 

解决方法:
下面的 ​​​json_str​​​ 就是​​JSON.stringify​​ 转换后的字符串
 

var cache = [];
var json_str = JSON.stringify(json_data, function(key, value) {
    if (typeof value === 'object' && value !== null) {
        if (cache.indexOf(value) !== -1) {
            return;
        }
        cache.push(value);
    }
    return value;
});
cache = null;    //释放cache
//来源: https://blog.51cto.com/u_15311558/5758502

二、structuredClone 深拷贝简介

注意: 用 JSON.parse(JSON.stringify(obj)) 实现深拷贝是一种奇技淫巧,在包含一般数字、字符串等类型属性的对象确实是种不错的方法,但存在一些短板,详细可见以下文章,另一种常见的方案是利用工具库Lodash 的 cloneDeep 函数

JS 现代化的深克隆

而现在的前端原生提供了全局的  structuredClone 函数用于深拷贝,​ 该方法利用可选的transfer参数还支持把原始值中的可转移对象转移到新对象,而不是把属性引用拷贝过去。 可转移对象与原始对象分离并附加到新对象;它们不可以在原始对象中访问被访问到。 ​

structuredClone() - Web API 接口参考 | MDN

structuredClone(value)
structuredClone(value, { transfer })  //transfer 可选,是一个可转移对象的数组,里面的 值 并没有被克隆,而是被转移到被拷贝对象上。


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中,JSON.stringify()方法的第三个参数可以控制缩进和空格。当这个参数是一个数值时,表示每一级缩进的空格数。例如,如果想要每级缩进4个空格,可以这样写代码: ``` let json1 = { title: "Json.stringify", author: ["浪里行舟"], year: 2021 }; let jsonText = JSON.stringify(json1, null, 4); ``` 这样,jsonText的值将会是带有缩进和空格的字符串。如果不设置第三个参数或将其设为0,则输出的JSON字符串将不包含任何空格或缩进。所以,JSON.stringify默认情况下是不会报错的。 然而,在引用中提到了一种情况,即在使用JSON.stringify()时可能会遇到空格报错。但这不是JSON.stringify本身的问题,而是在请求过程中使用了JSON.stringify(obj)的问题。在这个例子中,作者使用了一个库叫做"circular-json"来解决循环引用问题,但并没有提到具体的空格报错。 总结来说,JSON.stringify默认情况下是不会有空格报错的。如果你遇到了空格报错的问题,可能是在使用JSON.stringify的过程中出现了其他的问题,如循环引用等。建议你检查代码中是否有其他地方可能引起了空格报错的原因。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [你会用 JSON.stringify()? JSON.stringify一些坑](https://blog.csdn.net/qq_34648151/article/details/119143921)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [JSON.stringify(obj)报错的问题解决](https://blog.csdn.net/BUG_CONQUEROR_LI/article/details/125662193)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值