对象的深层拷贝
Flex 中对象的拷贝使用的是 ByteArray 类的 writeObject 方法。
1. 简单对象
直接上代码:
private function cloneObj(target:Object): *{ var copier:ByteArray = new ByteArray(); copier.writeObject(target); copier.position = 0; return copier.readObject(); }
var testTarget:Object = { name: 'zyc', email: 'zyc@zyc.com', sex: 'mail', addr: { pro: 'hz', city: ['hz','zh'] } }; var re1:Object = cloneObj(testTarget); trace(re1.addr.pro);
//输出 hz
writeObjet 方法实现的直接就是对象的深层拷贝。从上面的代码来看,as的拷贝要比js实现起来简单很多,不需要去遍历每个对象属性。
但是,as 中用的更多的还是各种自定义类的实例,往往也需要对实例进行拷贝操作。
2. 自定义类的实例
若直接使用上面的 cloneObject 方法拷贝类的实例,默认会忽略拷贝该实例对象。看代码:
// Person 为自定义类 有name,email,sex 三个属性及 hello 方法
var testTargetWithClass:Person = new Person();
testTargetWithClass.name = 'Jan'; testTargetWithClass.email = 'Jan@qq.com'; testTargetWithClass.sex = 'femail'; testTargetWithClass.hello();// 输出: Jan Jan@qq.com femail var re2:Object; re2 = cloneObj(testTargetWithClass); re2.hello();// error 对象不存在该方法
拷贝后的结果对象类型默认为Object 而不是 Person类型,所有也没有Person类的hello()方法。
解决办法是 registerClassAlias 方法,这个方法在之前往SharedObejct存入用户自定义类的数据时,也用到过。
这是一个全局函数,需有两个参数 registerClassAlias('aliasClass', customClass); aliasClass 名随便取,customClass为用户自定义的类名。
registerClassAlias("aliasPerson", Person); var re2:Object; re2 = cloneObj(testTargetWithClass); re2.hello();// 输出: Jan Jan@Jan.com femail
这里有两点需要注意:
1. 自定义类的构造函数里面不能有参数。上面的例子中,如果将Person类的构造函数,改成:
public function Person(name:String, email:String, sex: String = 'mail') { super(); _name = name; _email = email; _sex = sex; }
在registerClassAlias过程中,程序会报错。
2. 无法实现对 Flex 组件类的拷贝。如果需要拷贝一个 Spark 内的 Image 对象,不能使用这种方法。