深拷贝与浅拷贝的前提是:保证对象的属性是引用类型
拷贝:将对象的数据进行复制
深拷贝:拷贝的时候,将数据的所有引用结构都拷贝一份,那么数据在内存中独立
浅拷贝:拷贝的时候,只针对当前对象的属性进行拷贝,属性是引用类型不考虑,
浅拷贝只是将对象属性中的引用地址拷贝了,没有将属性所表示的对象拷贝出来,原对象和拷贝出来的对象共享一个对象。
浅拷贝问题: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>