来谈一谈深拷贝和浅拷贝的方法?

豆芽今天来谈一谈深拷贝和浅拷贝的区别和使用的方法。

二者的区别

区别建立在针对引用类型

浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响。

深拷贝:从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,前后的两个对象互不影响。

那么从简单的语言来说浅拷贝和深拷贝的区别,浅拷贝复制对象,当原对象改变的时候,复制对象也随之改变,而深拷贝复制对象,当原对象改变的时候,复制对象不会随着改变。

实现浅拷贝和深拷贝的方法

实现浅拷贝的方法

注意点:浅拷贝在第一层修改的时候新旧值不会发生变化,第二层开始,修改发生改变
1、Object.assign

let resList = { name: { resName: '曹豆芽' }, age: 21 };
let resListCopy = Object.assign({},resList);
resListCopy.name.resName = "小豆芽";
console.log(resList);
console.log(resListCopy);

在这里插入图片描述
我们可以很明显的看到resListCopy的对象值碰到改变的时候,resListCopy的值也随之改变。

2、concat浅拷贝数组

let resList = ['曹', '豆', '芽', { name: '曹豆芽' }];
let resListCopy = resList.concat();
resListCopy[3].name = "小豆芽";
console.log(resList);
console.log(resListCopy);                    

在这里插入图片描述
这里会发现当操作数组对象的值的时候,新旧的值都发生了变化。
3、slice浅拷贝

let resList = [{name:'曹豆芽'},1,2,3,4,5];
let resListCopy = resList.slice();
resListCopy[0].name = '小豆芽';

console.log(resListCopy);
console.log(resList);

在这里插入图片描述
这里会发现当操作数组对象的值的时候,新旧的值都发生了变化。

4、…展开运算符

let resList = [{name:'曹豆芽'},1,2,3,4,5];
let resListCopy = [...resList];
resListCopy[0].name = '小豆芽';

console.log(resListCopy);
console.log(resList);

在这里插入图片描述
同样也是一样这里会发现当操作数组对象的值的时候,新旧的值都发生了变化。

5.Array.from()

let resList = [{ name: '曹豆芽' }, 1, 2, 3, 4, 5];
let resListCopy = Array.from(resList);
resListCopy[0].name = '小豆芽';
console.log(resListCopy);
console.log(resList);

在这里插入图片描述
同样也是一样这里会发现当操作数组对象的值的时候,新旧的值都发生了变化。
6、手动实现

let resList = { name: { resName: "曹豆芽" }, age: 21 };
function beanSprouts(obj) {
         let target = {};
         for (let i in obj) {
                if (obj.hasOwnProperty(i)) {
                    target[i] = obj[i];
                }
         }
         return target;
}
let resListCopy = beanSprouts(resList);
resListCopy.name.resName = '小豆芽';
console.log(resListCopy);
console.log(resList);

在这里插入图片描述
同样也是一样这里会发现当操作对象的值的时候,新旧的值都发生了变化。

实现深拷贝的方法

1.JSON.parse(JSON.stringify())

let resList = { name: { resName: '曹豆芽' }, age: 21 };
let resListCopy = JSON.parse(JSON.stringify(resList))
resListCopy.name.resName = "小豆芽";
console.log(resList);
console.log(resListCopy);

在这里插入图片描述

改变数据新对象发生改变,旧对象不改变。

2.手写实现(递归)

let resList = { name: { resName: "曹豆芽" } }
function beanSprouts(obj) {
            let data = Array.isArray(obj) ? [] : {};
            if (obj && typeof obj === "object") {
                for (key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        //判断ojb子元素是否为对象,如果是,递归复制
                        if (obj[key] && typeof obj[key] === "object") {
                            data[key] = beanSprouts(obj[key]);
                        } else {
                            //如果不是对象,简单复制
                            data[key] = obj[key];
                        }
                    }
                }
            }
            return data;
}
let resListCopy = beanSprouts(resList)
resListCopy.name.resName = '小豆芽';
console.log(resList);
console.log(resListCopy);

在这里插入图片描述
同样这个时候我们会发现多次嵌套的值改变,新数据改变,就数据没有改变。

欢迎大家补充交流浅拷贝和深拷贝的方法🙏🙏

评论 209
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值