对象深拷贝

对象深拷贝是什么?

我们在js中对“字符串”、“数字”、“布尔值”进行拷贝一般只要“=”号就行了
但是在对象和数组中使用“=”,那只是进行“浅拷贝”(指针指向同一个堆内存地址)。

浅拷贝示例

将a赋值给b,a和b这两个栈内存变量的指针指向同一个堆内存地址

vara={name:"铅笔",color:"red"};
varb=a;
b.name="篮球";`在这里插入代码片`
console.log(a,b)

在这里插入图片描述
如上 b的值改变,会影响a的值,这在大多数情况下不是我们想要的。

深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
只要进行了深拷贝,就老死不相往来,谁也不会影响谁。

对象如何进行深拷贝?

目前只有 两种方法:
一个是递归,一个是JSON.stringify/JSON.parse方法

JSON.stringify/JSON.parse方法

vara={
name:"铅笔",
color:"red"
};
varb=JSON.parse(JSON.stringfiy(a));
b.name="篮球";
console.log(a,b)

在这里插入图片描述
如上成功进行深拷贝,但是这个方法不是所有情况下都适用的

vara={
name:"铅笔",
color:"red",
getName:function(){
console.log(this.name);
}
};
varb=JSON.parse(JSON.stringify(a));
b.name="篮球";
console.log(a,b)
b.getName()

在这里插入图片描述
undefined、function、symbol 会在转换过程中被忽略。。。,所以当对象里有这三个值的时候就不能使用这个方法

递归方法

functiondeepClone(obj1){
    varobj2=obj1.constructor===Array?[]:{};
    for(keyinobj1){
        //如果没这个属性就结束本次循环
        if(!obj1.hasOwnProperty(key)){
            continue;
        }
        //是对象就递归一下,不然就直接赋值
        if(typeof obj1[key]==='Object'){
            obj2[key]=deepClone(obj1[key]);
        }else{
            obj2[key]=obj1[key];
        }
    }
    returnobj2;
}
vara={
    name:'小明',
    age:18,
    say:function(){
        console.log('我叫'+this.name)
    }
};
varb=deepClone(a);
b.name='小环';
console.log(a,b);
b.say();

在这里插入图片描述

首层深拷贝

对目标对象的第一层进行深拷贝,然后子层的是浅拷贝,我称它为“首层深拷贝”

为什么叫首层深拷贝?
举个栗子:

vararr=['一个字符串',{name:'小环',age:21}];
b=arr.slice(0);
b[0]=123123;
b[1].name='小新';
b[1].age=6;
console.log(arr,b);
console.log('是否指向同一内存地址');
console.log(arr[1]===b[1]);

在这里插入图片描述

1、对”b[0]“重新赋值为“123123”,结果也如我们想象的那样互不影响。

2、但是对”b[1]“进行更改时,arr[1]也发生了相同更改。显然它们指向同一个对象
代码 arr[1] === b[1] 为 true,说明它们确实指向同一地址

所以首层是深拷贝,第二层后的目标都只是复制了一个引用是浅拷贝。

数组

slice方法

vararr=[1,2];
b=arr.slice(0);
b.push('aaa');
console.log(arr,b);

在这里插入图片描述

concat方法

vararr=[1,2];
b=arr.concat();
b.push('aaa');
console.log(arr,b);

在这里插入图片描述

三点运算符

vararr=[1,2];
b=[...arr];
b.push(99);
console.log(arr,b);

在这里插入图片描述

对象

Object.asign()方法

vara={
name:"铅笔",
color:"red",
getName:function(){
console.log(this.name);
}
};
varb=Object.assign({},a);
b.name="篮球";
console.log(a,b);
b.getName();

在这里插入图片描述

总结:

  1. 赋值运算符”=“拷贝对象实现的是浅拷贝,只拷贝对象的引用值;
  2. JavaScript 中数组和对象自带的拷贝方法都是“首层深拷贝”;
  3. JSON.stringify/JSON.parse 实现深拷贝,对目标对象有要求(非undefined,function、symbol);
  4. 若想真正意义上的深拷贝,请递归若想真正意义上的深拷贝,请递归
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值