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

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

相关推荐
竹林81811 分钟前
用 wagmi v2 + viem 监听链上事件,我踩了三天坑终于搞懂了实时日志与历史补全
javascript
Momo__15 分钟前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
只一18 分钟前
😭从回调地狱到 async/await:一文打通 Ajax 与 JS 异步编程
javascript
程序员小富21 分钟前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇22 分钟前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇22 分钟前
React中的forwardRef
前端·react.js·面试
槑有老呆30 分钟前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马32 分钟前
Verilog开发常见问题汇总解析
前端
子兮曰34 分钟前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端