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

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

相关推荐
m0_47119963几秒前
【vue】通俗详解package-lock文件的作用
前端·javascript·vue.js
GIS之路24 分钟前
GDAL 读取KML数据
前端
今天不要写bug39 分钟前
vue项目基于vue-cropper实现图片裁剪与图片压缩
前端·javascript·vue.js·typescript
用户47949283569151 小时前
记住这张时间线图,你再也不会乱用 useEffect / useLayoutEffect
前端·react.js
咬人喵喵1 小时前
14 类圣诞核心 SVG 交互方案拆解(附案例 + 资源)
开发语言·前端·javascript
问君能有几多愁~1 小时前
C++ 日志实现
java·前端·c++
咬人喵喵1 小时前
CSS 盒子模型:万物皆是盒子
前端·css
2401_860319522 小时前
DevUI组件库实战:从入门到企业级应用的深度探索,如何快速应用各种组件
前端·前端框架
韩曙亮2 小时前
【Web APIs】元素滚动 scroll 系列属性 ② ( 右侧固定侧边栏 )
前端·javascript·bom·window·web apis·pageyoffset