JS中对象的深浅克隆
一、对象的浅克隆
1.浅克隆:只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不进一步克隆它们,只是传递它们的引用
2.使用for…in…循环即可实现对象的浅克隆
var obj1 = {
a: 1,
b: 2,
c: [44, 55, 66]
};
// 实现浅克隆
var obj2 = {
};
for(var k in obj1){
// 每遍历一个k属性,就给obj2也添加一个同名的k属性
// 值和obj1的k属性值相同
obj2[k] = obj1[k];
}
// 为什么叫浅克隆呢?比如c属性的值是引用类型值,那么本质上obj1和obj2的c属性是内存中的同一个数组,并没有被克隆分开。
obj1.c.push(77);
console.log(obj2); // obj2的c属性这个数组也会被增加77数组
console.log(obj1.c == obj2.c); // true,true就证明了数组是同一个对象
二、对象的深克隆
1.克隆对象的全貌,不论对象的属性值是否又是引用类型值,都能将它们实现克隆
2.和数组的深克隆类似,对象的深克隆需要使用递归(面试常考)
var obj1 = {
a: 1,
b: 2,
c: [33, 44, {
m: 55,
n: 66,
p: [77, 88]
}]
};
// 深克隆
function deepClone(o) {
// 要判断o是对象还是数组
//要注意if语句的判断顺序,因为数组的typeof也是object,即如果先检测typeof o == 'object'
//数组和对象都为object ,先检测数组
if (Array.isArray(o)) {
// 数组
var result = [];
for (var i = 0; i < o.length; i++) {
result.push(deepClone(o[i]));
}
} else if (typeof o == 'object') {
// 对象
var result = {
};
for (var k in o) {
result[k] = deepClone(o[k]);
}
} else {
// 基本类型值
var result = o;
}
return result;
}
var obj2 = deepClone(obj1);
console.log(obj2); //被克隆
console.log(obj1.c == obj2.c); // false说明被克隆了,内存中不同的对象
obj1.c.push(99);
console.log(obj2); // obj2不变的,因为没有“藕断丝连”的现象
obj1.c[2].p.push(999);
console.log(obj2); // obj2不变的,因为没有“藕断丝连”的现象
想了解数组的浅克隆和深克隆点击即可