我要复制一份数组,内容完全一样,只是不同的引用
解决办法
使用concat( ) 方法或slice( ) 方法,另外还可以使用ArrayUtilities.duplicate( ) 方法,duplicate( )
方法可以创建递归复制
讨论
因为数组是复合类型,因此它的比较和复制都和基本类型不同。一个变量指向数组但是实际上
它并不包含数组数据,它只是指向内存中存放数组数据的位置。从优化的角度考虑,基本类型
的占用空间往往很小,但是符合类型如数组可以变得很大,如果我们在日常操作中经常复制整
个数组是非常不明智的,因此当你要复制数组时,ActionScript 并不是生成独立的一份拷贝,看
下面的例子:
首先我们看看基本类型是怎么复制的:
// 赋值数字5给变量
var quantity:int = 5;
// 拷贝quantity的值给另一个变量newQuantity.
var newQuantity:int = quantity;
// 改变quantity的值
quantity = 29;
trace(quantity); // 显示: 29
trace(newQuantity); // 显示: 5
我们看到,两者是互不影响的,也就是说基本变量拷贝的是值
现在我们看看数组的操作,和上面的例子不同,两个变量实际上都指向了同一个数组存贮空间。
当letters 变量改变数组内容时,也影响到newLetters变量:
// 赋值数组.
var letters:Array = ["a", "b", "c"];
// 拷贝letters 到newLetters.var newLetters:Array = letters;
// 两个数组包含相同内容
trace(letters); // 显示: "a,b,c"
trace(newLetters); // 显示: "a,b,c"// 改变letters的值
letters = ["d", "e", "f"];
// 另一个数组也变了
trace(letters); // 显示: "d,e,f"
trace(newLetters); // 显示: "d,e,f" (而不是"a,b,c")
其实这就像文件夹的两个快捷方式那样,两个快捷方式虽然名字不同,但是都指向同一个文件,
无论哪个对文件夹操作,另一个快捷方式也发生变化。
如果真要复制数组,可以调用数组的concat( ) 方法:
// 给数组赋值.
var letters:Array = ["a", "b", "c"];
//用concat( ) 创建新的数组
var newLetters:Array = letters.concat( );
// 两个数组内容一样
trace(letters); // 显示: "a,b,c"
trace(newLetters); // 显示: "a,b,c"
// 改变letters的值
letters = ["d", "e", "f"];
//不像上面的例子,这次两个数组内容不同了.
trace(letters); // 显示: "d,e,f"
trace(newLetters); // 显示: "a,b,c"
也可以用slice( ) 方法代替concat( ), 例如:
var newLetters:Array = letters.slice(0);
concat( ) 或slice( ) 方法复制一维整型下标的数组还可以,但是如果是多维的联合数组就不行
了,对于联合数组,不能使用concat( ) 或slice( ) 方法,对于多维数组,用concat( ) 或slice( )
只能复制顶层的数组,内部的就不能复制了,看下面的代码:var coordinates:Array = new Array( );
coordinates.push([0,1,2,3]);
coordinates.push([4,5,6,7]);
coordinates.push([8,9,10,11]);
coordinates.push([12,13,14,15]);
// 复制
var coordinatesDuplicate:Array = coordinates.concat( );// 替换元素
coordinatesDuplicate[0][0] = 20;
trace(coordinates[0][0]); //显示: 20
// 替换顶层元素.
coordinatesDuplicate[1] = [21,22,23,24];
trace(coordinates[1]); // 显示: 4,5,6,7
上面的代码coordinates 是个二维数组,coordinatesDuplicate 是coordinates的复制。但是,虽然
是复制,有些元素仍然引用了原始数组元素,这就意味你改变了一个,会影响另一个数组的内
容。实际上从上面的代码可以看出,只复制了顶层的数组,这一部分是互不关联的。
要想完全的复制数组,需要使用递归。ArrayUtilities.duplicate( ) 方法就是这样的做法,默认下
它也只复制一层数组,当第2个参数设为true时则是递归复制:
// 创建二维数组
var coordinates:Array = new Array( );
for(var i:int = 0; i < 4; i++) {
coordinates[i] = new Array( );
for(var j:int = 0; j < 4; j++) {
coordinates[i].push(String(i) + "," + String(j));
}
}
// 复制coordinates.
var newCoordinates:Array = ArrayUtilities.duplicate(coordinates, true) as Array;
// 替换
newCoordinates[0][0] = "a";// 使用toString() 方法输出
trace(ArrayUtilities.toString(coordinates));
trace(ArrayUtilities.toString(newCoordinates));
下面的例子演示用duplicate( ) 方法复制联合数组:
var coordinatesMap:Object = new Object( );
coordinatesMap.a = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.b = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.c = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.d = [{a: 1},{b: 2}, {c: 3}, {d: 4}];var newCoordinatesMap:Object = ArrayUtilities.duplicate(coordinatesMap, true);
newCoordinatesMap.a[0] = {r: 5};
trace(ArrayUtilities.toString(coordinatesMap));
trace(ArrayUtilities.toString(newCoordinatesMap));
两个例子可以看到,复制的数组改变不会影响原始数组。
文章来自: Flash家园()
详文参考:
阅读(3336) | 评论(1) | 转发(0) |