深克隆

浅克隆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
name: 'abc',
age: 18,
sex: 'male'
}

function clone(origin, target) {
var target = target || {};
for (var key in origin) {
target[key] = origin[key]
}
return target;
}
var newObj = clone(obj);

1570935515334

浅克隆的原始值属性更改,另一个对象不受影响。但是引用值属性一改就全都改了。

1570936074035

为了避免这个问题就需要进行深度克隆



深克隆

  1. 判断克隆对象,若为原始值(值类型)和null,直接返回
  2. 判断克隆对象是对象类型还是数组类型,分别result={}result=[]
  3. 遍历克隆对象,obj.hasOwnProperty(key)判断是非原型属性的,进行递归克隆
  4. 返回结果result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function deepClone(obj) {
// 1. 判断克隆对象,若为值类型和null,直接返回
if (typeof obj != 'object' || obj == null) {
return obj;
}

var result = {};
// 2. 判断克隆对象是对象类型还是数组类型,分别result={}和result=[]
if (Object.prototype.toString.call(obj) == '[object, Array]') {
result = [];
} else {
result = {};
}


// 3. 遍历克隆对象,obj.hasOwnProperty(key)判断是非原型属性的,进行递归克隆
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key]);
}
}
// 4. 返回结果result
return result;
}
1
2
3
4
5
6
7
8
9
10
11
// 测试用例
var obj = {
name: 'xi',
age: 20,
address: {
con: 'cn',
no: [11, 1]
},
hobbies: ['dance', 666, { kk: 5 }],
eat: function () { console.log(666); }
}

JSON深克隆

还可以使用 JSON 来实现深度克隆:

1
2
var objStr = JSON.stringify(obj);
var result = JSON.parse(Str);

但是json克隆无法克隆方法