深拷贝与浅拷贝

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

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

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

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

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

浅拷贝问题: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/hixxcom/p/7398273.html