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

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

相关推荐
童先生2 小时前
Nginx + Vue/React 前端 + API:防止路径混淆漏洞与跨域问题实战分享
前端·vue.js·nginx
黑夜照亮前行的路3 小时前
JavaScript 性能优化实战技术指南
javascript·性能优化
Stringzhua4 小时前
Vue数据的变更操作与表单数据的收集【6】
前端·javascript·vue.js
万少5 小时前
可可图片编辑 HarmonyOS 上架应用分享
前端·harmonyos
你的人类朋友5 小时前
git常见操作整理(持续更新)
前端·git·后端
无羡仙5 小时前
Webpack 核心实战:从零搭建支持热更新与 Babel 转译的现代前端环境
前端·webpack·前端框架
乐~~~5 小时前
el-date-picker type=daterange 日期范围限制
javascript·vue.js·elementui
你的人类朋友5 小时前
git中的Fast-Forward是什么?
前端·git·后端
初遇你时动了情5 小时前
uniapp vue3 ts自定义底部 tabbar菜单
前端·javascript·uni-app
JarvanMo6 小时前
天塌了?Flutter工程总监跑去苹果了?
前端