as3数据的浅复制和深复制

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

有两种复制方式:浅复制和深复制。这个概念不是数组特有的。对引用类型的数据复制方式有有浅复制和深复制的区别。

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

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

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

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

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

2.浅复制

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

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



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

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

示例

Copy code
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
/*结果为false 很正确
因为对于 Array 这个引用类型,“==”判断的是变量只有对象的引用是否相同,而不是内容相同。由于 bar 是 slice 方法(或者 concat 方法)返回的一个新数组,因此不和 foo 变量原有的数组引用相同
*/

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

//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 的运用

Copy code
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,确确实实把所有的元素都真正复制了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值