js中的浅拷贝和深拷贝

说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的“深度”,常见的对象都是“浅”的,也就是对象里的属性就是单个的属性,而“深”的对象是指一个对象的属性就是一个对象,也就是对象里面套对象,就像嵌套函数一样。

为什么要使用深拷贝和浅拷贝?

如果现有var obj={....}这个对象,想复制对象obj2,一贯的做法就是obj2=obj1,这时虽然obj2拥有了obj1的所有属性,但obj2却不是自由的,因为它的改动会影响到obj1,obj1的改动也会直接影响到obj2,这不是我们所希望的。所以要用到深拷贝和浅拷贝。


浅拷贝和深拷贝就是为解决对象的直接赋值后依然“链接”的问题。也就是公用一个引用,一个改变会影响另一个。下面是常见的浅拷贝:

var obj={
	a:10,
	b:20
};

function copy(obj){
	var newobj={};
	for(arr in obj)
	{
		newobj[arr]=obj[arr]
	}
	return newobj;
}

obj2=copy(obj);
alert(obj2.a);//成功复制出obj的a
obj2.a=555;  //更改了obj2的a
alert(obj2.a);//改变
alert(obj.a);//不变,obj2的改变不影响obj,说明拷贝后的对象和之前的对象不存在公用一个引用

浅拷贝可以解决常见的对象,但倘若对象不是常见的那种呢?比如说对象里还有子对象,那么用浅拷贝就不够彻底,比如以下代码:

var obj={
	a:{
		son1:'aa',  //obj对象里的a也是个对象
		son2:'bb'
	},
	b:20
};

function copy(obj){
	var newobj={};
	for(arr in obj)
	{
		newobj[arr]=obj[arr]
	}
	return newobj;
}

obj2=copy(obj);
alert(obj2.a.son1);//成功复制出obj的a
obj.a.son1=555;  //更改了obj的a.son2
alert(obj2.a.son1);//obj2的a.son1也随之改变
上面代码中,拷贝完成后更改了obj.a.son1,结果obj2.a.son1也随之改变,说明a依然存在公用同一个引用的现象,所以浅拷贝拷贝的并不彻底,不能彻底“挖到底” ,这时候深拷贝就该上场了,它能用递归的思想继续深挖,直到最底层为止。

下面就是深拷贝了:



var obj={
		a:{aa:10},//浅拷贝解决不了对象中的对象
		b: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);
	alert(obj.a.aa);//10
	alert(obj2.a.aa);//10 成功复制深层对象aa
	obj2.a.aa=22;  //改变obj2的a的aa
	alert(obj2.a.aa);//  改变
	alert(obj.a.aa);//10  不变
通过上述代码可看出深拷贝拷贝的非常彻底,做到真正意义上的杜绝相同引用的问题。


原文地址:https://www.cnblogs.com/chayangge/p/4288689.html