- 深拷贝:复制多层
- 浅拷贝:复制一层
在JavaScript使用过程中我们经常会遇到这样的场景;
var a = [1,2,3,4];
var b = a;
b[2] = 'other';
console.log(a); // [1,2,'ohher',4];
我们发现,当数组b的某一项发生变化时,数组a对应的项也发生了改变。
解析:当我们把变量a的值赋给变量b的时候,变量b只是复制了a的指针
,在堆内存中,变量a和变量b其实指向了同一个存储区域。
那么怎么才能实现把a拷贝一份给b,当b变化时a不受影响呢?
var arr = [1,["a","b"],3];
//var arr1 = arr.slice(0); // 与concat方法等效
var arr1 = arr.concat();
arr1[1][1] = "c";
arr1[3] = "4"
console.log(arr); //[1,["a","c"],3]
console.log(arr1); //[1,["a","b"],3,4]
通过上面的例子,我们发现,给数组添加slice或concat方法,实现了一层拷贝,既一维数组的值实现了拷贝,二维数组还是受影响,也就是没实现拷贝,这种情况通常称为浅拷贝
那么又怎么实现深拷贝呢,我们这通过一个对象来演示?
var a = {
name : {age:100}
};
var str = JSON.stringify(a);
var b = JSON.parse(str);
b.name = {age:200};
console.log(a.name.age); //100 不受影响
当b的age发生变化时,a中的age并不会受影响,这样我们就实现了深拷贝,这种方法也是现在比较流行的一种做法,但是IE下会有一些兼容性问题( IE低版本不认识JSON.stringify() ),所以我们通过封装函数的方法,重新实现一遍深拷贝和浅拷贝:
- 我们先建立一个对象
var obj = {
a:{
aa:10
},
b: 20
}
- 用for...in实现对象下面每个属性的拷贝
// 浅拷贝
function shallowCopy(obj) {
var newObj = {}
for(var attr in obj){
newObj[attr] = obj[attr]
}
return newObj;
}
var obj2 = shallowCopy(obj);
obj2.b = 21;
obj2.a.aa = 11;
console.log(obj.b); //20 不受影响
console.log(obj.a.aa); //11 受影响
- 用递归实现对象下面所有属性的拷贝
// 深拷贝
function deepCopy(obj){
if(typeof obj != 'object'){
return obj;
}
var newObj = {}
for(var attr in obj){
newObj[attr] = deepCopy(obj[attr]);
}
return newObj;
}
var obj2 = deepCopy(obj);
obj2.b = 21;
obj2.a.aa = 11;
console.log(obj.b); //20 不受影响
console.log(obj.a.aa); //10 不受影响
鉴于时间紧迫没有仔细说明,以后有改动时在好好整理!