水墨中国

对象深拷贝与浅拷贝

  • 15-04-01
  • font-end
  • javascript

##什么是克隆 ECMAScript变量包括两种不同的数据类型的值:基本类型之和引用类型值。

基本类型值:简单的数据段,Undefined、Null、Boolean、Number和String,他们是按值访问的,因为可以操作保存在变量中的实际的值。

引用类型值:是指那些可能有多个值构成的对象。引用类型的值是保存在内存中的对象。Javascript不允许直接访问内存中的位置。所以在操作对象时,实际上是在操作对象的引用而不是实际的对象。引用类型的值是按引用访问的。

对象克隆,就是对一个对象生成一个一模一样的对象.

在javascript中,使用简单的复制语句所实现的是原对象的一个引用,对其中任何一个对象属性方法的改变,都将会影响另一个的属性方法。

注:这里的对象不包括DOM对象,因为DOM对象有专用的clone()方法可用。

##浅拷贝 浅拷贝就是仅仅复制所考虑的对象,而不复制它所引用的对象。

//使用prototype原生属性创建clone方法
Object.prototype.clone = function(){
	var newObj = new Object();
	for(element in this){
		newObj[elements] = this[elements];
	}
	return newObj;
}	

直接循环遍历源对象的属性赋值给新对象,但这样的话,如果源对象属性中存在另一个对象的引用,那么就会造成复制不彻底。

var objOne = {
	'name':'name1',
	'info':{'identity':'identity1'}
};
objTwo = objOne.clone();	//浅复制一个对象
objTwo.name = 'name2';	//重新赋值
console.log(objOne.name);	//name1
console.log(objTwo.name);	//name2
objTwo.info.identity = 'identity2';	//改变identity的值
console.log(objOne.info.identity);	//identity2
console.log(objTwo.info.identity);	//identity2

当我们改变name属性值的时候,源对象的只没有改变,当我们改变克隆对象objTwo.info.identity=’PHPer’;时,原对象其值也发生了改变,这就是浅复制,不会去在乎原对象本身的引用.

##深拷贝 为了解决浅拷贝复制不彻底,所以就需要对源对象的引用对象也进行拷贝复制,采用递归实现;所以深拷贝就是要把复制的对象所引用的对象都复制一遍.

Object.prototype.cloneAll = function(){
	function clonePrototype(){}
	clonePrototype.prototype = this;	// this is the origin object
	var obj = new clonePrototype();
	for(var element in obj){
		if( typeof( obj[element] ) == "object" ){
			obj[element] = obj[element].cloneAll();	// 迭代
		}
	}
	return obj;
}
var objOne = {
    'name':'liangqi',
    'info':{'identity':'student'},
    'other':[1,2,3]
},
objTwo = objOne.cloneAll(); 	//深复制一个新对象
objTwo.name = 'godsee'; 	//重新赋值
console.log(objOne.name); 	//name1
console.log(objTwo.name); 	//name2
objTwo.info.identity = 'identity2'; 	//改变identity的值
console.log(objOne.info.identity); 	//identity1
console.log(objTwo.info.identity); 	//identity2
objTwo.other = [4,5,6,7,8];
console.log(objOne.other); 	//[1,2,3]
console.log(objTwo.other);	//[4,5,6,7,8]

通过深度复制,对源对象,以及源对象所有引用进行了复制,克隆了一个完全和源对象不相干的副本。

comments powered by Disqus