js中的克隆小解

/*js一般有两种不同数据类型的值: 
  基本类型(包括undefined,Null,boolean,String,Number),按值传递; 
  引用类型(包括数组,对象),按址传递,引用类型在值传递的时候是内存中的地址。 
克隆或者拷贝分为2种: 
  浅度克隆:基本类型为值传递,对象仍为引用传递。 
  深度克隆:所有元素或属性均完全克隆,并于原引用类型完全独立,即,在后面修改对象的属性的时候,原对象不会被修改。 

PS:

1:如果是一个简单的数组,元素中没有引用类型的值,可以直接用array.concat();或者array.slice(0);来深度拷贝一个数组,这样简单又高效。数组的concat()和slice()本来就会生成一个新的数组,原来的数组不会受影响。但是要注意的是你要确保被拷贝的数组中元素中没有引用类型的值。如果是一个简单的object对象可以用

for in循环来遍历复制就行了,但仅限于它的里面没有array.

2: 
这是另一种深度克隆的方法,很简单,很实用: 

代码如下:

var s = JSON.stringify( obj ); 
var o = JSON.parse( s ); 
 */
 

这种方式很好理解,对一个Object对象而言,先使用内置的JSON.stringify()函数,将其转化为数组。此时生成的字符串已经和原对象没有任何联系了,再通过JSON.parse()函数,将生成的字符串转化为一个新的对象。

而在新对象上的操作与旧对象是完全独立的,不会相互影响。这种方法的优点就是简单易懂,站在巨人的肩膀上,使用js内置函数来实现,不需要太大的开销。

而这种方式有一个非常致命的问题,它只能对Object对象实现深拷贝,对于Function等对象,JSON.stringify()函数会直接返回undefined。因为现在的Object对象里面基本都会有Function类型存在(如果没有Function存在,也没有

拷贝的必要了)。

 
 
 
 
 
 
下面是自己写的函数:

function clone(obj)
{

var o;
if (obj instanceof Array)
{
o=[];
var len =obj.length;
while(len){
o[len-1]=clone(obj[len-1]);
len--;
}
return o;

}
else if(obj instanceof Object)
{
o={};
for(var k in obj)
{
o[k]=clone(obj[k]);
}
return o;


}
else {return obj ;}
}


var obj1=[23,"dsds",43];
var obj2=clone(obj1);
obj2.push(32);
alert(obj2);
alert(obj1);

下面是精简过得函数:

function clone1(obj)
{

 if(typeof obj !== "object")

{   return obj;  

}

var o=obj instanceof Array?[]:{};

for(var key in obj)
{
o[key]=clone1(obj[key]);

 

};
return o;

 }

PS:以上是自己的理解,有错误的话希望给意见。

posted @ 2014-09-21 19:26  林璐  阅读(203)  评论(0编辑  收藏  举报