AS3中对象的深度复制

转自:http://joe-feng.iteye.com/blog/1401959

复制复杂对象(例如ArrayCollection,XML)时,可以使用ObjectUtil.copy()方法,代码如下:

 

As代码 复制代码  收藏代码
  1. //Object对象:  

 

As代码 复制代码  收藏代码
  1. var obj1:Object = {name:"name01",data:"data01"};  
  2. var obj2:Object = ObjectUtil.copy(obj1);  
  3. obj2.name = "name02";  
  4. obj2.data = "data02";  
  5. ArrayCollection:  
  6. var ac2:ArrayCollection = ObjectUtil.copy(ac) as ArrayCollection;  

 

As代码 复制代码  收藏代码
  1. //XML:  

 

As代码 复制代码  收藏代码
  1. var myXML2:XML = ObjectUtil.copy(myXML1) as XML;  

 

 

 因为copy方法返回的结果是Object类型,如果对于自定义的对象,copy方法返回结果类型就会丢失,变成Object,而且无法转换成自定义的对象,我们需要对ObjectUtil.copy()方法进行修改,让他支持自定义的类型。

源码如下:

 

As代码 复制代码  收藏代码
  1. public static function copy(value:Object):Object  
  2.     {  
  3.         var buffer:ByteArray = new ByteArray();  
  4.         buffer.writeObject(value);  
  5.         buffer.position = 0;  
  6.         var result:Object = buffer.readObject();  
  7.         return result;  
  8.     }  

 

 

 所做修改如下:

 

As代码 复制代码  收藏代码
  1. import flash.utils.ByteArray;  
  2. import flash.utils.getQualifiedClassName;  
  3. import flash.net.*;  
  4. import src.*;  
  5.   
  6. function cloneObject(source:Object) :* {  
  7.     var typeName:String = getQualifiedClassName(source);//获取全名  
  8.     trace(”输出类的结构”+typeName);  
  9.     //return;  
  10.     var packageName:String = typeName.split(”::”)[0];//切出包名  
  11.     trace(”类的名称”+packageName);  
  12.     var type:Class = getDefinitionByName(typeName) as Class;//获取Class  
  13.     trace(type);  
  14.     registerClassAlias(packageName, type);//注册Class  
  15.     //复制对象  
  16.     var copier:ByteArray = new ByteArray();  
  17.     copier.writeObject(source);  
  18.     copier.position = 0;  
  19.     return copier.readObject();  
  20. }  

 

 

 有的人说用复制对象那一段不就可以了吗,但是实际上行不通。对于数组深度复制来说, 复制对象的后面4句代码就足够了。

 

As代码 复制代码  收藏代码
  1. var a1:Array=[1,2,3];  
  2. var a2:Array =cloneObject(a1);  
  3. var a3:Array = a1;  
  4. a1.push(”youmila”);  
  5. trace(”a1:”+a1+”a2:”+a2+”a3″+a3);  

 

 

 但是对于对象来说肯定不行,用列子测试下,src.youmila.as 代码: 

 

As代码 复制代码  收藏代码
  1. package src{  
  2.   
  3. public class youmila{  
  4.     private var $_name:String =”youmila”;  
  5.     private var $_num:Number =0;  
  6.     public function youmila():void{  
  7.     trace($_name);  
  8. }  
  9.   
  10. public function secondFunc():void{  
  11.     $_num++;  
  12.     trace(”this a called function $_num::”+$_num);  
  13. }  
  14. }  
  15. }  

 

 

 yapollo.as 代码: 

 

As代码 复制代码  收藏代码
  1. package {  
  2.   
  3. public class yapollo{  
  4.     private var $_name:String =”yapollo”;  
  5.     public var $_num:Number =0;  
  6.     public function yapollo():void{  
  7.     trace($_name);  
  8. }  
  9.   
  10. public function secondFunc():void{  
  11.     $_num++;  
  12.     trace(”this a called function $_num::”+$_num);  
  13. }  
  14. }  
  15. }  

 

 测试实例: 

 

As代码 复制代码  收藏代码
  1. var uml1:youmila = new youmila();  
  2. var uml2 = cloneObject(uml1);  
  3. trace(”类型”+getQualifiedClassName(uml2));  

 

 输出结果: 

 

youmila

类型Object

 

原来的对象类型丢失了,所以对于对象而言,四行不够,必须用registerClassAlias来保存类的别名,以用于丢失后恢复类的类型,测试实例: 

 

As代码 复制代码  收藏代码
  1. var uml1:youmila = new youmila();  
  2. var uml2 = cloneObject(uml1);  
  3. trace(”类型”+getQualifiedClassName(uml2));  
  4. var apollo:yapollo = new yapollo();  
  5. apollo.secondFunc();  
  6. var apollo2 = cloneObject(apollo);  
  7. trace(”第一次输出复制对象的$_num值”+apollo2.$_num);  
  8. trace(”类型”+getQualifiedClassName(apollo2));  
  9. apollo2.secondFunc();  
  10. trace(”第二次输出复制对象的$_num值”+apollo2.$_num);  

 

 输出结果: 

 

youmila

输出类的结构src::youmila

类的名称src

[class youmila]

youmila

类型src::youmila

yapollo

this a called function $_num::1

输出类的结构yapollo

类的名称yapollo

[class yapollo]

yapollo

第一次输出复制对象的$_num值1

类型yapollo

this a called function $_num::2

第二次输出复制对象的$_num值2

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值