js实现深拷贝——JSON.parse(JSON.stringify(obj))和拓展运算符区别对比

JSON.parse(JSON.stringify(obj)) 是一种常见的实现深拷贝的方法。它将对象转换为 JSON 字符串,然后再解析这个字符串,从而创建了一个新的对象。这个过程会创建一个完全独立的对象,实现了深拷贝。 但是在某些情况下可以实现对象的深拷贝,但是也存在一些特殊情况和限制:

1.可以使用它来做深拷贝的情况:

  1. 对象是纯粹的JSON数据结构,即它只包含简单的数据类型(如字符串,数字,布尔值,数组,对象),并且没有包含函数,正则表达式,日期对象等特殊的类型时候可以使用。 例如:
js 复制代码
        const obj={
            name:'Marcos',
            age:12,
            obj2:{
                name:'Marcos2',
                age:12,
                obj3:{
                    name:'Marcos3',
                    age:12
                }
            },
            arr2:[1,2,3,4,5]
        }
        const objCopy =JSON.parse(JSON.stringify(obj))
        console.log(objCopy)

2.对象中不包含循环引用,即对象的属性之间没有互相引用导致循环结构。如果是循环结构会导致JSON.stringify报错。 例如:

js 复制代码
        const obj={
                name:'Marcos2',
                age:12,
        }
        obj.obj2=obj
        
        const objCopy =JSON.parse(JSON.stringify(obj))
        console.log(objCopy)

2.特殊情况:

1.对象中包含 undefined、Symbol、function 类型的属性时,在转换为 JSON 字符串时会被忽略丢失。

js 复制代码
 let obj = {
            age: 18,
            fn: function () {
                console.log('fn');
            },
            bb: undefined
        };
        const objCopy = JSON.parse(JSON.stringify(obj))
        console.log('obj', obj);
        console.log('objCopy', objCopy);

2.对象中包含 Date 类型的属性时,转换为 JSON 字符串后会变成字符串形式,而不再是 Date 对象。

js 复制代码
        let obj = {
            age: 18,
            date:new Date()
        };
        const objCopy = JSON.parse(JSON.stringify(obj))
        console.log('obj', obj);
        console.log('objCopy', objCopy);

3.对象中包含 RegExp 类型的属性时,转换为 JSON 字符串后会变成空对象 {}

js 复制代码
        let obj = {
            age: 18,
            reg:new RegExp('^[a-zA-Z0-9_-]{6,16}$'),
            error:new Error('用户名不能为空')
        };
        const objCopy = JSON.parse(JSON.stringify(obj))
        console.log('obj', obj);
        console.log('objCopy', objCopy);

综上所述,JSON.parse(JSON.stringify(obj)) 可以实现简单的 JSON 数据结构的深拷贝,但在处理包含特殊类型或循环引用的对象时,可能会出现问题,在实际开发中还需要结合实际情况使用。

拓展运算符和 JSON.parse(JSON.stringify(obj))对比区别

扩展运算符(spread operator)... 属于浅拷贝。它可以用于创建一个新的对象或数组,并将原始对象或数组的属性或元素复制到新对象或数组中。对于对象来说,使用扩展运算符只会复制对象的第一层属性,而嵌套对象仍然是引用关系,因此并不是完全独立的拷贝。

区别在于深拷贝会递归地复制所有层级的对象,使得原对象和拷贝后的对象完全独立,而浅拷贝只会复制对象的第一层属性,嵌套对象仍然是引用关系。因此,深拷贝会更加彻底地复制整个对象结构,而浅拷贝只会复制对象的最外层属性。

相关推荐
Setsuna_F_Seiei1 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲3 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙3 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan5 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen5 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理6 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
IT_陈寒6 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
Blanche15007 小时前
利用 RAG 为答疑机器人扩展知识范围
前端
天若有情6737 小时前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具
SoonITer7 小时前
怎样构建一个 Agent-friendly 的网站
前端·agent