您的位置:首页 > 其它

数组与对象的深浅复制

2016-04-19 21:10 423 查看
1.JavaScript中的数组是一种特殊的对象。作为索引的数字在内部被转换为字符串类型,这是因为JavaScript对象的属性名必须是字符串。

所以数组只是一种特殊的对象。

2.数组的浅复制与深复制
浅复制:

var nums=[1,2,3];
var samenums=nums;

nums[0]=0;
console.log(samenums[0]); //0 这里是0,而不是复制过来时候的1.


这就是浅复制,被赋值数组不过是一个指向原有数组的引用而已。
所以原数组改变,新赋值数组也会改变。
这样的情况有时候会影响我们的操作,也会不是我们所期望的。

深复制:
这时候我们就要进行深复制了。
方法一:遍历复制

for(var i=0;i<nums.length;i++){
samenums[i]=nums[i];
}

这时候我们再:nums[0]=0;
console.log(samenums[0])    //1,这里依旧是1.


方法二:slice,slice(0)巧办法进行修改,返回的是一个副本。

var a=[1,2];
var b= a.slice(0);
a[0]=10;
alert(b[0])    //1


三:对象的深浅复制

var a={
ao:1,
at:2
}
var b=a;
a.ao=2;
alert(b.ao) //2 因为进行的是浅复制。


对象的深复制,
一种是遍历。
还有一个是jQuery的$.extend(a,b)。

var a={ name: "John",
location:{
city:"Boston",
county:"USA"
}
}
var b={};
$.extend(b,a);    //这里是直接将a对象合并到b对象中去
a.name="zqz";
console.log(b.name);    //依旧为 John



***************
$.extend()是对jQuery的直接扩展
$.fn.extend()是对jQuery的实例对象的扩展
***************


四:问题衍生
这里引出一个问题:
$.extend()的问题!
extend(dest,src1,src2,src3...)       含义是:将src1,src2,src3...合并到dest中
extend(boolean,dest,src1,src2,src3...) //深度拷贝与浅拷贝

extend(true,dest,src1,src2,src3...)    //深度拷贝,会连src中的嵌套的对象也进行合并
extend(false,dest,src1,src2,src3...) //浅拷贝,不会将src中的嵌套的对象也进行合并

不管是哪种extend的操作,都会涉及合并问题。那个这个合并规则又是什么呢?我们不去人云亦云。直接用例子,自己找。

第一种:dest不是空对象,是个已经有属性的对象。extend(dest,src1)

var a={ name: "leslie",
location:{
city:"beijing",
county:"china"
}
}
var b={
name:'zqz',
location:{
city:'beijing',
county:'mars',
work:'ito'
}
};

$.extend(b,a);
console.log(b);
//结果:
{
location:{
city:"beijing",
county:"china"
},
name:"leslie"
}


结果:a与b有相同项:a覆盖b,即使b中的内嵌对象也会覆盖a中的内嵌对象
a与b有不同项:a一样覆盖b,也就是说,不管b中有多少不同项(多出项或少出项),都是以a的为准。
--以覆盖项(a)为尊!

第二种:dest不是空对象,是个已经有属性的对象。extend(dest,src1,src2)

var a={ name: "leslie",
location:{
city:"beijing",
county:"china"
}
}
var b={
name:'zqz',
location:{
city:'beijing',
county:'mars',
work:'ito'
}
}

var c={
location:{
city:'wuhan',
county:'mars',
work:'itos',
hobby:'study'
}
}

$.extend(a,b,c);
console.log(a);

//结果
a={
location:{
city:'wuhan',
county:'mars',
work:'itos',
hobby:'study'
},
name:'zqz'
}


**反正a的‘优先级’最低,只要前面头相同的项时候,都会直接被覆盖。然后向b推移。

(下面关于extend的深度与浅拷贝:摘自RascallySnakejQuery.extend 函数详解

五、Jquery的extend方法还有一个重载原型:

extend(boolean,dest,src1,src2,src3...)


第一个参数boolean代表是否进行深度拷贝,其余参数和前面介绍的一致,什么叫深层拷贝,我们看一个例子:

var result=$.extend( true,  {},
{ name: "John", location: {city: "Boston",county:"USA"} },
{ last: "Resig", location: {state: "MA",county:"China"} } );


我们可以看出src1中嵌套子对象location:{city:"Boston"},src2中也嵌套子对象location:{state:"MA"},第一个深度拷贝参数为true,那么合并后的结果就是:

result={name:"John",last:"Resig",location:{city:"Boston",state:"MA",county:"China"}}


也就是说它会将src中的嵌套子对象也进行合并,而如果第一个参数boolean为false,我们看看合并的结果是什么,如下:

var result=$.extend( false, {},
{ name: "John", location:{city: "Boston",county:"USA"} },
{ last: "Resig", location: {state: "MA",county:"China"} }
);


那么合并后的结果就是:

result={name:"John",last:"Resig",location:{state:"MA",county:"China"}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: