深拷贝与浅拷贝

深拷贝与浅拷贝的前提是:保证对象的属性是引用类型

拷贝:将对象的数据进行复制

深拷贝:拷贝的时候,将数据的所有引用结构都拷贝一份,那么数据在内存中独立

浅拷贝:拷贝的时候,只针对当前对象的属性进行拷贝,属性是引用类型不考虑,

浅拷贝只是将对象属性中的引用地址拷贝了,没有将属性所表示的对象拷贝出来,原对象和拷贝出来的对象共享一个对象。

浅拷贝问题:Pcopy做某些操作的时候,很有可能把p的属性也修改了。

Dom操作拷贝节点时,当节点下还有节点(就是他的属性)就会出现浅拷贝的问题。

所以Dom操作拷贝节点时要用深拷贝。

浅拷贝代码实现

<script>
//var car = {name:'法拉利'};
//var p = {name:'张三',age:'19',car:car};
//
//var pCopy = p;//这不是拷贝,这是赋值。
//下面是拷贝代码。
//var pCopy = {};
//pCopy.name = p.name;
//pCopy.name = p.age;
//pCopy.car = p.car;

//下面是封装好的代码
var p = {
	name:'张三',
	age:'19',
	gender:'男',
	copy:function () {
		//1.创建一个空对象
		var temp = {};
		//2.拷贝属性
		for (var k in this) {
			temp[ k ] = this[ k ];
			}
		//3.返回对象
		return temp;
		}
	};
	var p2 = p.copy();//p.copy()是函数的调用,把返回值给p2,p.copy是把copy这个属性(function)给他
	//测试
	p.name = '李四';
	p.age = '20';
</script>

对于值类型,浅拷贝是对值的复制,对于对象来说,浅拷贝是对对象地址的复制,并没有开辟新的内存空间,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,而深拷贝则是开辟新的内存空间,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。深拷贝实现代码如下:

<script>
//深拷贝实现原理:利用对象的动态特性给每一个对象添加一个deepCopy的属性,属性值是一个函数,
// 函数内部用typeof判断属性的类型如果是值类型直接拷贝一份,如果是引用类型则调用对象的deepCopy
//方法完成拷贝,这样拷贝出来的两个对象除deepCopy这个函数外就是完全独立的,
// 因为typeof(function) ==== 'function'.
//var car = {name:'法拉利'};
//var p = {name:'张三',age:19,gender:'男',car:car};
//var p2 = {};
//p2.name = p.name;
//p2.age = p.age;
//p2.gender = p.gender;
//p2.car = {};//拷贝的属性是引用类型的时候,新创建一个空对象
//p2.car.name = p.car.name;
//p.car.name = '兰博基尼';//测试

//利用面向对象的思想进行封装
var deepCopy = function () {
	//1.创建一个新对象
	var temp = {};
	//2.拷贝属性,如果属性有引用类型就需要深拷贝
	for (var k in this) {
		if (typeof(this[ k ]) === 'object' ) {
			temp[ k ] = this[ k ].deepCopy(); 
			}else {
				temp[ k ] = this[ k ];
				}
		}
	//3.返回对象
	return temp;
	};
var car = {name:'法拉利'};
var p = {name:'张三',age:19,gender:'男',car:car};
//让所有对象都有拷贝方法
car.deepCopy = deepCopy;
p.deepCopy = deepCopy;
var p2 = p.deepCopy();//完成拷贝
//进行测试
p.name = '李四';
p.age = 20;
p.gender = '女';
p.car.name = "兰博基尼";
</script>
原文地址:https://www.cnblogs.com/laijun/p/7395979.html