Deep&Shallow cloning

首先在js中数据类型分为两种,基础数据类型和引用数据类型
JavaScript原始类型:Undefined、Null、Boolean、Number、String、Symbol
JavaScript引用类型:Object

1.浅克隆

浅克隆之所以叫浅克隆,是因为对象只会被克隆最外面一层,至于对象内的对象还是通过引用指向同一块内存

2.个人理解:深拷贝,为解决对象(引用类型),复制时新旧对象使用同一块内存

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
58
59
60
61
62
63
64
65
66
67
68
69
70
//基本类型的复制,传的是值,
var obj={a:1,b:2,c:3,d:{e:5}};

// var obj1=obj;
// obj.a=2;
// console.log(obj==obj1);




//浅拷贝

// function qian(obj){
// var newobj={};
// for( k in obj){
// newobj[k]=obj[k];
// }
// return newobj;
// }
// var obj1=qian(obj);
// obj1.d.e=6;
// console.log(obj);



//深拷贝
function deep(obj){
var newobj={};
for( k in obj){
//对遍历到的元素,进行类型判断
if(typeof obj[k]=="object"){
//对object类型的原素再次遍历判断
newobj[k]=deep(obj[k]);
}else{
//基本类型直接拷贝
newobj[k]=obj[k];
}
}
return newobj;
}
var obj1=deep(obj);
obj1.d.e=6;
console.log(obj1==obj);//false






// jquery 有提供一个$.extend可以用来做 Deep Copy。
var $ = require('jquery');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false

// 函数库lodash,有提供_.cloneDeep用来做 Deep Copy。
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false

下面的文字,鉴于掘金

当然也有传闻中的,序列/反序列(JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,这两个方法结合起来就能产生一个便捷的深克隆.)
要想实现一个靠谱的深克隆方法,上一节提到的序列/反序列是不可能的

它存在这些坑
1.他无法实现对函数 、RegExp等特殊对象的克隆
2.会抛弃对象的constructor,所有的构造函数会指向Object
3.对象有循环引用,会报错

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
// 构造函数
function person(pname) {
this.name = pname;
}

const Messi = new person('Messi');

// 函数
function say() {
console.log('hi');
};

const oldObj = {
a: say,
b: new Array(1),
c: new RegExp('ab+c', 'i'),
d: Messi
};

const newObj = JSON.parse(JSON.stringify(oldObj));

// 无法复制函数
console.log(newObj.a, oldObj.a); // undefined [Function: say]
// 稀疏数组复制错误
console.log(newObj.b[0], oldObj.b[0]); // null undefined
// 无法复制正则对象
console.log(newObj.c, oldObj.c); // {} /ab+c/i
// 构造函数指向错误
console.log(newObj.d.constructor, oldObj.d.constructor); // [Function: Object] [Function: person]
1
2
3
4
5
6
const oldObj = {};

oldObj.a = oldObj;

const newObj = JSON.parse(JSON.stringify(oldObj));
console.log(newObj.a, oldObj.a); // TypeError: Converting circular structure to JSON

如果,第一段代码都无法看懂,那推荐看更高深的解读
掘金大佬:寻找海蓝96 https://juejin.im/post/5abb55ee6fb9a028e33b7e0a

Share
5 min. read