zoukankan      html  css  js  c++  java
  • (转)as3数组的深复制和浅复制

    自:http://bbs.9ria.com/blog-1532-16623.html

    当数组中存在Bitmap而进行深度复制时,数据类型丢失,折磨了两天,参考了各种资料无果(资料如下),尝试进行如下操作解决了!有时候思维往往被禁锢,跳出来,其实很简单!

     
    var newArr:Array = [];
    for (var i:int = 0; i < oldArr.length; i++ ) {
    newArr.push(oldArr[i]);
    }
     

     

     
     
     

     

    --------------------------------------------------------------------------------------

     

    as3中通过ByteArray进行对象的深度拷贝(不丢失数据类型!)

    来源:http://www.webjx.com/flash/actionscript-15470.html

    as3中通过ByteArray可以进行对象的深度拷贝

    import flash.utils.ByteArray;
    import flash.utils.getQualifiedClassName;
    import flash.net.*;
    import src.*;
    function cloneObject(source:Object) :* {
    var typeName:String = getQualifiedClassName(source);//获取全名
    trace(”输出类的结构”+typeName);
    //return;
    var packageName:String = typeName.split(”::”)[0];//切出包名
    trace(”类的名称”+packageName);
    var type:Class = getDefinitionByName(typeName) as Class;//获取Class
    trace(type);
    registerClassAlias(packageName, type);//注册Class

    //复制对象
    var copier:ByteArray = new ByteArray();
    copier.writeObject(source);
    copier.position = 0;
    return copier.readObject();
    }

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

    var a1:Array=[1,2,3];

    var a2:Array =cloneObject(a1);

    var a3:Array = a1;
    a1.push(”youmila”);
    trace(”a1:”+a1+”a2:”+a2+”a3″+a3);

    但是对于对象来说肯定不行

    用列子测试下
    src.youmila.as 代码:

    package src{
    public class youmila{
    private var $_name:String =”youmila”;
    private var $_num:Number =0;
    public function youmila():void{
    trace($_name);

    }

    public function secondFunc():void{
    $_num++;
    trace(”this a called function $_num::”+$_num);

    }
    }

    }

    yapollo.as 代码:

    package {
    public class yapollo{
    private var $_name:String =”yapollo”;
    public var $_num:Number =0;
    public function yapollo():void{
    trace($_name);

    }
    public function secondFunc():void{

    $_num++;
    trace(”this a called function $_num::”+$_num);

    }

    }
    }

    测试实例

    var uml1:youmila = new youmila();
    var uml2 = cloneObject(uml1);
    trace(”类型”+getQualifiedClassName(uml2)); 
    输出结果:

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

    测试实例

    var uml1:youmila = new youmila();

    var uml2 = cloneObject(uml1);
    trace(”类型”+getQualifiedClassName(uml2));

    var apollo:yapollo = new yapollo();

    apollo.secondFunc();
    var apollo2 = cloneObject(apollo);
    trace(”第一次输出复制对象的$_num值”+apollo2.$_num);
    trace(”类型”+getQualifiedClassName(apollo2));

    apollo2.secondFunc();
    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 

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

     

    复制一个数组,是指生成一个新的数组,内容和原有数组一样。数组赋值经常需要用到,比较重要。

    有两种复制方式:浅复制和深复制。这个概念不是数组特有的。对引用类型的数据复制方式有有浅复制和深复制的区别。两者的区别是: 深复制会复制整个填充的对象,包括该对象中其他引用类型和值类型的值;而浅复制只复制了一个对象中所有引用,它没有值的复制.

    1.何时用浅复制?何时用深复制?

    当数组元素全部都是基元数据类型时,即全部是值类型时,复制是没有浅复制和深复制的分别的。若要复制,使用下文中的浅复制方法即可。

    但是当数组元素全部是复杂数据类型,即引用数据类型时,那么复制就会有两种选择:一种是浅复制,一种是深复制。

    当 数组部分元素是基元数据,部分元素是复杂数据类型时,也要考虑该采用那种复制方式。由于ActionfScrip 3 数组不是类型化数组,允许存储不同类型的数据,因此这种情况也很常见的。对于基元数据类型的元素,不论用哪种方式复制,执行效果都是一样。只有对于复杂数 据类型元素,才有深复制和浅复制的区别。

    比如数组A[1,"string",[1,2,3]],其第三个元素是数组,属于复杂类型元素,则需要考虑两种复制方式的影响。其余连个元素,一个数值型,一个是字符串型,都属于基元数据类型,不需要考虑采用何种复方式。
    2.浅复制

    生成数组浅复制的方法很简单,只需要调用原书组的 slice 方法或者 concat 方法,不传任何参数,即可生成数组的浅复制。用法如下。

    var copy:Array = originaArray.concat();var copy:Array = originaArray.slice();

    使用浅复制生成的新数组,其各个元素存放的只是引用。两个数组中相同位置的元素存放的引用指向同一个对象。那么,如果对该元素操作,等于就是操作引用指向的对象。如果该对象状态发生变化,那么也会影响到另一个数组中相应位置的元素。这一点需要注意。

    下面示例生动详细地展示了浅复制的方法,以及运用浅复制必须要注意的要点。
    先解释一下代码内容。
    有一个数组foo,其第一个元素是 String 型,属于值类型。它的第二个元素是 Array 型,第三个元素是 Object型, 都属于引用类型。使用 slice 方法(或 concat 方法)生成数组的 foo 的浅复制——数组 bar 。然后改动数组 bar 的元素内容,再和数组 foo 的元素一一比较。结果发现,改动数组 bar 中的值类型元素不会影响 foo 中的相应元素。但改动 bar 中的引用类型元素,则 foo 中相对应的元素也改变了。不仅新手,老手也常常忘了这一点,从而吃苦头。

     var objectElement:Object = {name:"kingda",web:"www.kingda.org "};
    var arrayElement:Array    = [1,2,3];

    var foo:Array = ["a string element",arrayElement,objectElement];
    trace (foo);
    //输出 foo 的内容:a string element,1,2,3,[object object]

    //1.使用slice方法生成 foo 的浅复制,赋值个 bar
    var bar:Array = foo.slice();
    //也可以用:foo.concat();

    //2.比较 foo 和 bar
    trace (bar);
    //输出浅复制bar的内容:a string element,1,2,3,[object object]
    //结果和foo完全一样


    trace(foo==bar);
    //输出:false


    trace (foo[0] == bar[0]);
    //输出:true
    //注意,第一个元素是值类型,因此“==”是根据值(value)来判断的
    trace (foo[1] == bar[1]);
    trace (foo[2] == bar[2]):


    //3. 下面我们来挨个改变bar数组的所有元素,再来一一比较foo和bar
    bar[0] = "a new string in bar";
    bar[1][0] = 1000;
    bar[2].web = "www.actiongscript3.cn ";

    trace (foo);
    //输出:a string element ,1000,2,3,[object object]
    //注意,foo中的内容除了第一个元素,其余也跟着bar变了。改变了bar,同时也改变了 foo中
    //引用类型元素的内容
    trace (bar);
    //输出:a new string in bar ,1000,2,3,[object object]
    //可以看到,bar除了第一个元素和现在的foo不同外,其余都一样

    //怎么知道第三个元素也变了呢?我来trace一下它的web属性
    trace (foo[2].web);
    //输出:www.actionscript3.cn
    //果然foo中第三个元素的web属性也变了
    trace(bar[2].web);
    //输出:www.actionscript3.cn

    3.深复制

    使用深复生成的新数组,其所有元素都是真正的数组元素的备份。这时两个数组中相同未知的元素,存放的是不同的引用,指向不同的对象。但是这两个独享的状态是完全一致的。

    如何生成深复制?这就需要使用到强大的ByteArray 类了。方法见示例:
    示例:数组的深度复制:ByteArray 的运用

    var objectElement:Object ={name:"kingda",web:"www.kingda.org" };
    var foo:Array = ["a string element",arrayElement,objectElement];
    //以下4行深复制数组 foo
    var fooBA:ByteArray = new ByteArray();
    fooBA.writeObject(foo);
    fooBA.position = 0;
    var bar:Array = fooBA.readObject() as Array;

    trace (bar);
    //输出:a string element,1,2,3,[object object]
    trace (foo == bar);
    //输出:false
    //表明foo和bar持有的是两个不同对象的引用
    trace (foo[0] == bar[0]);
    //输出:true
    //由于第一个元素是String型,因此“==”判断值相等,返回真
    trace (foo[1] == bar[1]);
    //输出:false
    //第二个元素是Array型,因此“==”判断引用是否相同,若不同,返回假
    trace (foo[2] == bar[2]);
    //输出:false
    //第三个元素是Object型,因此“==”判断引用是否相同,若不同,返回假

    //以下3行改变bar的元素
    bar[0] = "a new string in bar";
    bar[1][0] = 1000;
    bar[2].web = "www.actionscript3.cn" ;
    //在看foo是否受影响
    trace (foo);
    //输出:a string element,1,2,3,[object Object]
    trace (bar);
    //输出:a new string in bar,1000,2,3,[object Object]
    trace (foo[2].web);
    //输出:www.kngda.org
    trace (bar[2].web);
    //输出:www.actionscript3.cn
    //可以看出,bar的改变并没有影响foo,确确实实把所有的元素都真正复制了

     

    同样对于ArrayCollection一样存在这种情况.而对于其浅复制来说:

    var arrCollection:ArrayCollection=new ArrayCollection(new Array);模仿Array即可

     

    --------------------------------------------------------------------------------------------------------------------------------------

     

     

    As3 深度克隆某个对象,支持Vector和Array(不丢失类别)

     

    博客分类: As3

    prototype

    clone 某个对象,支持Vector类型和Array类型

     

    需要引用类库as3-commons-reflect

     

    http://www.as3commons.org/as3-commons-reflect/

     

     

    /** 

    * 深度clone某个对象,包含Vector 和 Array 

    */         

    public static function clone (_obj : * ): * 

        var returnCloneObj :*; 

        var objType : Type = Type . forInstance (_obj );

        

        if (_obj is Vector .<*> || _obj is Array )

        { 

            returnCloneObj = new objType . clazz ();

            for each (var eachCloneObj :* in _obj )

            { 

                returnCloneObj . push (cloneObj (eachCloneObj ));

            } 

        } 

        else 

        { 

            returnCloneObj = cloneObj (_obj );

        } 

        return returnCloneObj ;

     

    /** 

    * clone 只能clone简单对象的所有的public属性 

    */ 

    private static function cloneObj (_obj : * ): * 

        var objType : Type = Type . forInstance (_obj );

        var cloneObj :* = new objType . clazz ();

        for each (var field : Field in objType . properties )

        { 

            if (field is Variable || field is Accessor && Accessor (field ). writeable && field . name != 'prototype' )

            { 

                cloneObj [ field . name ] = _obj [ field . name ]; 

            } 

        } 

        return cloneObj ;

  • 相关阅读:
    Asp.Net Mvc Filter
    使用 EntityFramework后把一个对象序列化成json字符串引起循环引用的问题
    RCTF2020 calc & EasyBlog & swoole
    GKCTF-EzWeb+redis未授权访问
    BJD3rd
    http走私
    网鼎杯2020青龙组 web writeup
    De1CTF 2020 部分web
    js相关trick总结
    xss常见编码解析
  • 原文地址:https://www.cnblogs.com/wonderKK/p/2875466.html
Copyright © 2011-2022 走看看