23.对象深拷贝

  • assign方法可以将第二个参数的对象的属性和方法拷贝到第一个参数的对象中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 深拷贝
class Person{
name = "lnj";
age = 34;
}
let p1 = new Person();
let p2 = new Object();


// assign方法可以将第二个参数的对象的属性和方法拷贝到
//第一个参数的对象中
Object.assign(p2, p1);
// console.log(p2);
p1.name = "zs";
console.log(p1.name);
console.log(p2.name);
// 注意点: 只有被拷贝对象中所 有属性都是基本数据类型,
// 以上代码才是深拷贝
  • 注意点: 只有被拷贝对象中所 有属性都是基本数据类型,以上代码才是深拷贝
  • 不会互相影响各自对基本变量的赋值了

那么如果属性都是引用类型,如何保证还是深拷贝?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Person{
name = "lnj";
cat = {
age : 3
};
scores = [1, 3, 5];
}
let p1 = new Person();
let p2 = new Object();

depCopy(p2, p1);

function depCopy(target, source) {
// 1.通过遍历拿到source中所有的属性
for(let key in source){
// console.log(key);
// 2.取出当前遍历到的属性对应的取值
let sourceValue = source[key];
// console.log(sourceValue);
// 3.判断当前的取值是否是引用数据类型
if(sourceValue instanceof Object){

let subTarget = new sourceValue.constructor;
target[key] = subTarget;
depCopy(subTarget, sourceValue);
}else{
target[key] = sourceValue;
}
}
}

要看懂上面,要知道几个前置知识

  • 所有的引用类型都是对象,通过sourceValue instanceof Object 判断为true,因为在原型链上,Object原型对象在末尾,任何一个对象如果找不到属性方法都会到Object原型对象上找,那么,通过sourceValue instanceof Object 判断为true
  • 对象的constructor===new它出来的构造函数,以此可以new出来一个空白的实例,这是不同于任何对象的地址
1
let subTarget = new sourceValue.constructor;