深拷贝与浅拷贝

浅拷贝

浅拷贝只复制一层对象的属性,并不包括对象里面的为引用类型的数据

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
var obj1 = {
'name' : '熊大',
'age' : '10',
'language' : [1,[2,3],[4,5]],
};

var obj2 = obj1;//把对obj1的引用赋值给了obj2,他们都是指向同一个引用,对obj2的更改会改变obj1


var obj3 = shallowCopy(obj1);
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}

obj2.name = "熊二";
obj3.age = "20";

obj2.language[1] = [22,33];
obj3.language[2] = [44,55];//浅拷贝只复制一层对象的属性,这里操作的和obj1是同一个堆内存的数据

console.log(obj1);
//obj1 = {
// 'name' : '熊二',
// 'age' : '10',
// 'language' : [1,[22,33],[44,55]],
//};

console.log(obj2);
//obj2 = {
// 'name' : '熊二',
// 'age' : '10',
// 'language' : [1,[22,33],[44,55]],
//};

console.log(obj3);
//obj3 = {
// 'name' : '熊大',
// 'age' : '20',
// 'language' :[1,[22,33],[44,55]],
//};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//浅拷贝另外的实现
//对象中的数据未基本类型时可用
let source1 = {
'name' : '熊大',
'age' : '10',
'language' : [1,[2,3],[4,5]]
};
let result = Object.assign({},source1);
result.name = '熊二';
result.language[1] = [22,33];
//source1 = {
// 'name' : '熊大',
// 'age' : '10',
// 'language' : [1,[22,33],[44,55]],
//};

//result = {
// 'name' : '熊二',
// 'age' : '10',
// 'language' : [1,[22,33],[44,55]],
//};

深拷贝

深拷贝是对对象以及对象的所有子对象进行拷贝。
思路就是递归调用刚刚的浅拷贝,把所有属于对象的属性类型都遍历赋给另一个对象即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var deepCopy = function(obj) {
const keys = Object.keys(obj)//得到obj里所有的keys

const newObject = {};

for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (typeof obj[key] === 'object') {
newObject[key] = deepCopy(obj[key])//是引用类型就递归调用
} else {
newObject[key] = obj[key]
}
}
return newObject
}
1
2
//深拷贝另外的实现,有局限性(对象里无function)
JSON.parse(JSON.stringify(obj))

当其有function时,可参考如下文章 [‘https://juejin.im/entry/5a44ac5cf265da432a7be37e']

参考另一篇更全的文章 [‘https://yanhaijing.com/javascript/2018/10/10/clone-deep/']