你的位置:首页 > Java教程

[Java教程]JS深拷贝继承


所谓深拷贝,就是子对象不紧继承父对象的非引用属性,还能继承父对象的引用属性(Object,Array),当子对象对继承的引用类型属性做修改时,父对象的引用类型不会被修改。

我们先写个浅拷贝的封装函数:

 

function extendCopy(parent){  var child={};  for(var i in parent){    child[i]=parent[i];  }  child.uber=parent;  return child;}

 

接下来写个深拷贝的封装函数:

 

function deepCopy(p,c){  var c=c||{};   for(var i in p){    if(typeof p[i]==="object"){      c[i]=(p[i].constructor===Array)? [] : {};
       deepCopy(p[i],c[i]); }else{ c[i]=p[i]; } } return c;}


分析两个函数有何不同,extendCopy方法是将父对象的属性和方法逐个的拷贝给子对象,当遇到引用类型的属性时,比如数组,那么若对子对象拷贝而来的数组进行重写时,父对象对应的数组也会随之改变,因为他们指向的是同一地址。

而deepCopy方法:

举个栗子:

var parent={

  score:[1,2,3,4];

}

 

var child=deepCopy(parent);

执行deepCopy函数后,当执行到

if(typeof parent[score]==='object')时,

child[score]=[];

再执行deepCopy(parent[score],child[score]);

此时typeof p[i]就不是'object'类型了,而是number类型,

所以

child[score][1]=parent[score][1]=1;

child[score][2]=parent[score][2]=2;

child[score][3]=parent[score][3]=3;

child[score][4]=parent[score][4]=4;

在return child[score];

这样就完成了深拷贝,child[score]和parent[score]不是指向同一个地址了。但此时两者值相同,只是地址不同,若再对child[score]做修改,parent[score]不会有任何变化。

我们来试验一下:

 

var Shape={  color:"blue",  name:"shape",  size:[1,2,3,4],  getName:function(){    return this.name;  }}    var circle=deepCopy(Shape);   var tran=extendCopy(Shape);  circle.size.push(5,6);  console.log(circle.size); //[1,2,3,4,5,6]  console.log(Shape.size);//[1,2,3,4]  深拷贝父对象值没有变化  tran.size.push(5,6,7,8);  console.log(circle.size); //[1,2,3,4,5,6]  console.log(tran.size);//[1,2,3,4,5,6,7,8]  console.log(Shape.size);  //[1,2,3,4,5,6,7,8] 浅拷贝随着tran.size的改变,Shape.size也会随之改变,

 

上述demo很好的验证了浅拷贝和深拷贝的区别