数组基础
package com.powerflasher.SampleApp { import flash.display.Sprite; public class FDTTest extends Sprite { public function FDTTest() { var array:Array = ["Sam", "Jack", "Peter"]; array["7"] = "Nick"; array[-1000] = "Jason"; trace("array[-1000] = " + array[-1000]); trace("array.length = " + array.length); } } }
最后输出的结果是:
array[-1000] = Jason array.length = 8
我们再用JavaScript来编写同样的代码:
var array = ["Sam","Jack","Peter"]; array["7"] = "Nick"; array[-1000] = "Jason"; alert("array[-1000] = " + array[-1000]); alert("array.length = " + array.length);
最后弹框输出的结果与ActionScript的是一致的。
在使用Java的时候涉及到集合的序列化和拷贝的时候需要考虑浅复制还是深复制的问题。不仅仅是Java,使用引用来操作对象的语言应该都会有这个问题。ActionScript也不例外。
可以理解浅复制就是只复制集合中对象的引用,而深复制会复制对象的本身。
ActionScript对数组进行浅复制非常的简单,只需要调用数组本身的slice方法或者contact方法就可以。slice方法是从参数的指定范围截取一个新的子数组返回,concat可以将参数拼成一个新数组返回。当不传递任何参数给这两个方法的时候将会完成数组的浅复制。
package com.powerflasher.SampleApp { import flash.display.Sprite; public class FDTTest extends Sprite { public function FDTTest() { var array1:Array = ["Sam", ["Jack", "Peter"]]; var array2:Array = array1.concat(); trace("array2:" + array2); array2[1][1] = "Tom"; trace("array1:" + array1); trace("array2:" + array2); } } }
最终输出的结果是:
array2:Sam,Jack,Peter array1:Sam,Jack,Tom array2:Sam,Jack,Tom
因为array2和array1持有对同一个元素的引用,通过array2进行改变,array1也改变了。
如果要进行深复制,那该怎么做呢?需要借助ByteArray这个类型的对象,ByteArray是一个byte数组的封装,提供了操作byte缓冲区的一些方法,跟Java中的java.nio.ByteBuffer类似。
package com.powerflasher.SampleApp { import flash.utils.ByteArray; import flash.display.Sprite; public class FDTTest extends Sprite { public function FDTTest() { var array1:Array = ["Sam", ["Jack", "Peter"]]; var byteArray:ByteArray = new ByteArray(); byteArray.writeObject(array1); byteArray.position = 0; var array2:Array = byteArray.readObject() as Array; trace("array2:" + array2); array2[1][1] = "Tom"; trace("array1:" + array1); trace("array2:" + array2); } } }
输出结果:
array2:Sam,Jack,Peter array1:Sam,Jack,Peter array2:Sam,Jack,Tom
有两点挺有意思,一是ByteArray跟java.nio.ByteBuffer不一样,没有提供flip方法,当数据写进byte缓冲区之后要再读出来,需要手工将position指向0;二是用as运算符做类型转换是一个比较优雅的解决方案,用一条语句即检查了类型又做了转换,而且不会抛异常,在Java中这是一个很烦的过程,需要先instanceof判断,在进行转换,如果不判断,类型错了还会抛出ClassCastException这种运行时异常。
ActionScript是一种支持函数式风格的编程,在actionscript中,函数是Function类型的对象,函数可以作为其它函数的参数进行传递进行回调。个人感觉函数回调这种风格用的比较多的地方一个是事件的处理,一个是操作集合。
ActionScript数组提供了针对数组每个元素操作的方法,这些方法都是在函数回调的基础之上构建的。操作有以下几种:
forEach(callback:Function, thisObject:* = null):void //针对数组中的每一个元素进行操作
filter(callback:Function, thisObject:* = null):Array //指定一个过滤条件,从原数组中过滤出符合条件的新元素返回这些新元素的数组,回调函数返回单个新数组的元素。
map(callback:Function, thisObject: * = null):Array //使用回调函数来操作数组中的每一个值,并利用回调函数返回的结果组成新的数组返回。
some(callback:Function, thisObject: * = null):Boolean //只要有一个元素回调的结果为true就返回true
every(callback:Function, thisObject: * = null):Boolean //需要全部的元素回调结果返回true才返回true
以上方法回调函数的形式都是: function 回调函数名(currentElement:Object, index:int, array:Array):返回值类型{}, 需要注意函数的类型必须符合这种形式,否则执行时会出现错误。
package com.powerflasher.SampleApp { import flash.display.Sprite; public class FDTTest extends Sprite { public function FDTTest() { var array:Array = [100, 9, 200, 2]; array.sort(function(arg1:int, arg2:int):int { return arg1 - arg2; }); trace("array:" + array); } } }