# 题目描述
请你完成一个函数 —— 实现对象参数的深拷贝并返回拷贝之后的新对象
要求:
- 需要考虑函数,正则,日期和
ES6
新对象 - 需要考虑循环引用问题
# 分析
- 判断是否为对象是否为空,判断对象类型
- 因为有函数,正则这些类型,所以要用正则来判断,如果是这些类型的对象,就直接返回一个新的该对象 —— 利用
target.constructor
来访问到父类的构造函数 - 循环引用 —— 要使用map来存储<属性值,深拷贝对象>,如果该属性已经被深拷贝过了,就返回当前的深拷贝对象
- 开始深拷贝 —— 递归
# 测试用例
function test() {
const o1 = {
name: "g",
age: 18,
o: { name: "o" },
a: [1, 2],
r: new RegExp(),
d: new Date(),
};
o1.self = o1;
const o2 = _completeDeepClone(o1);
o1.name = "z";
o1.age = 1;
const judge =
o1.name !== o2.name &&
o1.age !== o2.age &&
o1.o !== o2.o &&
o1.a !== o2.a &&
o1.r !== o2.r &&
o1.d !== o2.d &&
o1.self.self.self.self.self.self.self.self.self === o1.self &&
o1.self !== o2.self;
return judge;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 代码实现
function test() {
const o1 = {
name: "g",
age: 18,
o: { name: "o" },
a: [1, 2],
r: new RegExp(),
d: new Date(),
};
o1.self = o1;
const o2 = _completeDeepClone(o1);
o1.name = "z";
o1.age = 1;
const judge =
o1.name !== o2.name &&
o1.age !== o2.age &&
o1.o !== o2.o &&
o1.a !== o2.a &&
o1.r !== o2.r &&
o1.d !== o2.d &&
o1.self.self.self.self.self.self.self.self.self === o1.self &&
o1.self !== o2.self;
return judge;
};
const _completeDeepClone = (target, map = new Map()) => {
if (!target || typeof target != "object") {
return target;
}
let reg = /^(RegExp|Funtion|Data|Map|Set)$/;
// constructor指向构造函数
const constructor = target.constructor;
if (reg.test(constructor.name)) {
return new constructor(target);
}
// 防止递归调用一个属性
if (map.get(target)) {
return map.get(target);
}
const cloneTarget = Array.isArray(target) ? [] : {};
map.set(target, cloneTarget);
Object.keys(target).forEach((prop) => {
if (target.hasOwnProperty(prop)) {
// 递归拷贝
cloneTarget[prop] =
typeof target[prop] === "object"
? _completeDeepClone(target[prop], map)
: target[prop];
}
});
return cloneTarget;
};
console.log(test());
// true
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57