In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

汎用性の高いディープコピーを考える

Get Adobe Flash player
by shohei909 01 Nov 2010
    Embed
/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5fQr
 */

//sample of deep copy
//Adobeのlivedocsに載っていた方法でのディープコピーがうまく機能しなかったので、
//汎用性の高いディープコピー(深いコピー)を考える。


//下のコードで,次のようなインスタンスのディープコピーを実現できる。
//deep copy
//  Object,Array,Vectorクラスのインスタンス
//  clone関数で自分自身の複製を返すインスタンス(例: Event,Matrix,Point,BitmapDataなど)
//  Object,Array,Vectorや、clone関数で自分自身の複製を返すインスタンスを含むObject,Array,Vector

//  ただし、
//    プリミティブ型,Object,Array,Vectorクラス以外のインスタンスはシャローコピーになる。
//     自分自身の複製を返さないclone関数があると正しく動作しない。


package {
    import flash.utils.ByteArray;
    import flash.geom.Matrix;
    import flash.display.Sprite;
    import com.bit101.components.TextArea;    
    import flash.utils.getQualifiedClassName;    
    public class FlashTest extends Sprite {
        public function FlashTest() {
            // write as3 code here..
            var ba:ByteArray = new ByteArray();
            ba.writeDouble(1232134.413);
            
            var objA:Object = {
                a:1,
                b:2,
                c:3,
                arr:[1,2,3], 
                o:{    
                    a:1,
                    str:"xyz", 
                    m: new Matrix(0,0,1,0),
                    ba: ba,
                    vec:Vector.<String>( [null,null,null] )
                    
                }, 
                f:function f():void{ trace("ok?") } // functionはディープコピーにならない
            };
            
            
            var objB:Object = objA;                //比較用 shallow copy
            var objC:Object = clone( objA );    //deep copy1
            
            
            objA.o.vec[0] = "objA";
            objB.o.vec[1] = "objB";
            objC.o.vec[2] = "objC";
            
            var text:TextArea = new TextArea( this );
            text.setSize( 465, 465 );
            text.text = "\nobjA:" + string(objA) + 
                    "\n\nobjB(shallow copy):" + string(objB) +
                    "\n\nobjC(deep copy):" + string(objC);
                    
        }
    }
}

//ディープコピーを行う関数1 (deep copy1)
import flash.utils.getQualifiedClassName;
import flash.utils.getDefinitionByName;
import flash.utils.ByteArray;
function clone(arg:*):*{
    var name:String = getQualifiedClassName(arg);
    var cl:*;
    if( name == "Object" || name == "Array" || arg is Vector.<*> || name == "flash.utils::Dictionary" ){
        var classDef:Class = getDefinitionByName(name) as Class;
       cl = new classDef();
        
        var flag:Boolean = false; 
        for( var s:Object in arg ){
            cl[s] = clone( arg[s] );
            flag = true;
        }
        return cl
    }else if( name == "flash.utils::ByteArray" ){
       cl = new ByteArray()
       cl.readBytes(arg);
       cl.position = 0;
       return cl;
    }else if( arg is Object && arg.hasOwnProperty("clone") && arg.clone is Function ){        
        return arg.clone();
    }
    return arg;
}






function string(arg:*, index:String = ""):String{
    var str:String = "";
    var name:String = getQualifiedClassName(arg);
    if( name == "Object" ){
        for( var s:String in arg){str+="\n        "+ index + s + " : " + string(arg[s],index+"        " )}
        return "{ " + arg.toString() +  str  + "\n" + index + "}";
    }
    return arg;
}