浅拷贝定义:
复制引用数据类型后,修改这个新对象的属性值,不会影响原始对象的值,这就叫浅拷贝。
引用类型赋值存在的问题,如下:
//eg. 1.1
var a={name:'小白'};
var b = a;
b.name ='小黑';
alert(a.name); //破功:小黑,原始对象属性被改变
//eg. 1.2
var c=[1,2,3];
var d=c;
d.push(4);
alert(c); //破功:1234,原始数组被改变
eg.1.1中实际上我们想要的效果是b.name=’小黑’后,a.name仍然是小白。所以我们需要做浅拷贝。
为什么以上例子没有达到效果。
原因在于:
对象、数组甚至函数,在赋值的时候都是引用传递的,传递是的地址,一个指针。于是,新对象和原始对象使用了同一个地址空间。所以我们修改新对象的属性,实际上也在修改原始对象的属性,甚至修改了所有引用这个地址的其它对象的属性。
那么要达到,互不影响的效果,我们需要浅拷贝。例子如下:
// eg.1.3 手工浅拷贝
function shallowCopy(obj){
var newObj={};
for(var attr in obj){
newObj[attr]=obj[attr];//分别对每个属性进行赋值。
}
return newObj;
}
var a = {name:'小白'};
var b = {};
shallowCopy(a);
b.name = '小强';
alert(a.name); //成功:原始对象属性没变,还是"小白",达到目的!
//eg. 1.4
//使用jquery extend 进行浅拷贝
var a={name:'小白'};
var b ={};
$.extend(b,a);
b.name = '小黑';
alert(a.name); //成功:原始对象属性没变,还是"小白",达到目的!
但是浅拷贝还是存在问题,它只能解决对象属性是值类型的的对象的复制,但如果对象属性还嵌套对象,或者多层嵌套。那么浅拷贝也存在问题。这就需要深拷贝来解决。
对于属性的多层嵌套,浅拷贝存在的问题,如以下代码,:
//e.g 1.5
function shallowCopy(obj){
var newObj={};
for(var attr in obj){
newObj[attr]=obj[attr];//分别对每个属性进行赋值。
}
return newObj;
}
var a = {name : {firstName: 'liu'}};
var b = {};
shallowCopy(a);
b.name.firstName = 'wang';
alert('the right answer is liu : ',a.name.firstName); //破功:这里a.name.firstName会变成wang.
由于属性也是对象,所以在for循环中对属性的赋值,也成了引用赋值。所以修改b.name.firstName = ‘wang’; a.name.firstName也是wang。
如何解决,用深拷贝,见以下代码:
//eg.1.6 手工深拷贝
//
function deepCopy(obj){
if(typeof obj !== 'object'){
console.trace();
return obj;
}
var newObj ={};
for(var attr in obj){
newObj[attr] = deepCopy(obj[attr]);
}
return newObj;
}
var a = {name : {firstName: 'liu'}};
var b = {};
deepCopy(a);
b.name.firstName = 'wang';
alert('the right answer is liu : ',a.name.firstName); // 成功:liu
//eg.1.7
// 采用 jquery extend 进行深拷贝
var a = {name : {firstName: 'liu'}};
var b = {};
$.extend(true,b,a);
b.name.firstName = 'wang';
alert('the right answer is liu : ',a.name.firstName); //成功: liu
参考: