- 浏览: 100863 次
文章分类
- 全部博客 (56)
- AS3 基础 (13)
- AS3 Loading (3)
- AS3 XML (1)
- AS3 数组 (10)
- AS3 包 (0)
- AS3 声音 (0)
- AS3 时间日期 (0)
- AS3 鼠标 (1)
- AS3 组件 (0)
- AS3 滤镜 (2)
- AS3 特效 (0)
- AS3 与后台 (0)
- AS3 影片控制 (3)
- AS3 算法 (2)
- AS3 素材 (0)
- AS3 书籍 (0)
- AS3 实例 (0)
- AS3 其他 (2)
- 未处理 (1)
- Flex 组件 (0)
- Flex 与ASP.NET (0)
- delphi 基础 (11)
- SQL 基础 (3)
- Delphi combox (1)
- 电脑基础 (0)
- 吃穿住行 (0)
- delphi 数据库 (0)
- SQL 实例代码 (0)
- delphi 报错 (1)
- delphi 函数 (1)
- as3 个人作品 (0)
最新评论
-
hanker888:
眼睛都看花了,能否推荐一下目前用得最多的?
常用flash引擎和框架
大概谈了以下4个简单的问题,如果读者对它们的答案都了如指掌,大可不必看了。
1)在AS3中实现数组的复制共有几种方法? 2)如何使用ByteArray实现数组的深拷贝? 3)如何实现所有对象的深拷贝? 4)为什么在Flash Player中不能使用ByteArray拷贝显示对象?
1,使用concat复制数组var arr1 :Array = "as3 expert programming by sban".split(/ /); var arr2 :Array = arr1.concat(); trace(arr2.length, arr2);//5 as3,expert,programming,by,sban concat的本意是连合两个旧数组的元素,并返回新数组。新数组元素依次按旧数组1,旧数组2的元素排列。当旧数组2为空参时,可返回旧数组1的拷贝。但它的拷贝是浅拷贝,看如下代码: var arr1 :Array = "as3 expert programming by sban".split(/ /); arr1.unshift({count:1}); var arr2 :Array = arr1.concat(); arr2[0].count++; trace(arr2[0].count, arr1[0].count);//2 2 上例代码使用unshift在数组arr1底部推入一个Object对象,它具有一个count属性,由于concat仅是拷贝数组元素的引用,所以arr2[0].count与arr1[0].count的值是相同的。 那么在AS3中,哪些对象是引用对象,哪些是值对象?有哪些对象作为数组元素时,是引用类型? 2,使用slice返回新数组var arr1 :Array = "as3 expert programming by sban".split(/ /); var arr2 :Array = arr1.slice(); trace(arr2);//as3,expert,programming,by,sban slice用于从指定索引开始分割旧数组,以返回新数组,可用于数组拷贝。与concat类似,slice仍是浅拷贝。那么,如果实现数组元素的深拷贝呢?
3,使用for关键字复制数组var arr1 :Array = "as3 expert programming by sban".split(/ /); var arr2 :Array = new Array(arr1.length); var n :int = arr1.length; for(var j:int=0; j<n; j++) { arr2[j] = arr1[j]; } trace(arr2);//as3,expert,programming,by,sban 使用for关键字复制数组元素,在这里毫无疑问也是引用复制(对于引用对象类型)。值得提出的是,使用for关键字并不能保证可以遍历出所有数组元素,因为也不能保证复制的有效性。 为什么说for不能保证遍历数组的所有元素? 除了使用for,使用for..in或for each in或while同样也可以实现类似的数组复制,初学者可以自行实现一下练练手。 4,如何使用ByteArray实现数组的深拷贝有时候,我们希望在修改新拷贝的数组元素时,不会对源数组产生任何影响,这便需要深拷贝。 在AS3中可以使用ByteArray复制源对象,产生新对象,以下是Adobe在Livedoc中提供的引用对象深拷贝方法: public function clone(source:Object): Object { var r: ByteArray = new ByteArray(); r.writeObject(source); r.position = 0; return (r.readObject()); } 运用该方法修改前面的拷贝示例,以实现数组元素的深拷贝,代码示例如下: var arr1 :Array = "as3 expert programming by sban".split(/ /); arr1.unshift({count:1}); var arr2 :Array = clone(arr1) as Array; arr2[0].count++; trace(arr2.length, arr2);//6 [object Object],as3,expert,programming,by,sban trace(arr2[0].count, arr1[0].count);//2 1 从输出结果可以看出,在该示例中,arr2[0]与arr1[0]便不再是同一个对象。貌似这样我们就可以实现对象的深拷贝了,但这个方法是有局限的。它适用于在AS3中定义的数据类型,包括所有基元类型及由基元类型组合的复合类型,却并适用于在Flash Player中定义的显示对象类型,如Sprite,MovieClip等。
下面我们用实验的方法,验证Adobe提供的ByteArray clone方法不能拷贝Flash Player中定义的显示对象。首先,sban定义一个TextFieldSprite对象,它继承于Sprite,主要代码如下: public class TextFieldSprite extends Sprite { public function TextFieldSprite() { var t :TextField = new TextField(); t.text = 'as3 expert programming by sban'; t.autoSize = TextFieldAutoSize.LEFT; addChild(t); } } 这个代码很简单,仅是在构造时添加一个文本。接下来,使用前面类似方式,实例化一个数组,然后进行复制: var arr1 :Array = [new TextFieldSprite(), new TextFieldSprite()]; var arr2 :Array = clone( arr1 ) as Array; trace(arr2);//[object Object],[object Object] 代码运行到这里,还相安无事。由输出可以看出,貌似我们的深拷贝成功了。但问题是,深拷贝出来的对象却是不能使用的,这里的不能使用指它们不能被添加进显示列表中。当sban试图把它们添加进显示列表,代码示例如下: arr2.forEach( function(item :DisplayObject, index :int=-1, arr :Array = null) :void { addChild(item); } ); 这段时间在编译时没有任何问题,在运行时则会引发如下异常: TypeError: Error #1034: 强制转换类型失败:无法将 Object@228bd09 转换为 flash.display.DisplayObject。 at Array$/_forEach() at Array/http://adobe.com/AS3/2006/builtin::forEach() at Main()[C:\Users\virgo\Documents\ria\ad3_fd\src\Main.as:22] 实验证明,在AS3中,不能使用ByteArray深拷贝显示对象。 那么,为什么在AS3中不能使用ByteArray拷贝显示对象?使用它拷贝出来的对象为什么不能转换为DisplayObject? 5,如何实现所有对象的深拷贝?使用ByteArray仅能在一定范围内实现数组的深拷贝,那么我们应当如何实现所有对象的深拷贝呢? 目前在AS3中,没有一个像ByteArray clone那么简单而又适用所有类型的数组深拷贝方法。在项目开发中,我们需要定义一个IClonaeble接口: package sban.as3Expert.interfaces { /** * * @author sban <http://sban.biz/> * Gmail: sban.net@gmail.com * * 2010-4-24 * */ public interface ICloneable { function clone() :ICloneable; } } 然后让可能需要深拷贝的每一个对象实现这个接口,在方法clone中new一个新对象,并把当前对象的数据一一赋值给新对象。例如修改前面用到的TextFieldSprite对象,如下: package sban.as3Expert { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import sban.as3Expert.interfaces.ICloneable; /** * * @author sban <http://sban.biz/> * Gmail: sban.net@gmail.com * * 2010-4-24 * */ public class TextFieldSprite extends Sprite implements ICloneable { public function TextFieldSprite() { super(); t = new TextField(); t.text = 'as3 expert programming'; t.autoSize = TextFieldAutoSize.LEFT; addChild(t); } private var t :TextField; public function setText(s :String) :void { t.text = s; } public function getText() : String { return t.text; } public function clone() :ICloneable { var r :TextFieldSprite = new TextFieldSprite(); r.setText( this.getText()); return r; } } } 调用其clone方法用于深拷贝该对象,每一个对象负责其本身的clone方法的具体实现,因为只有它自己知道它有哪些数据需要被复制。
复制TextFieldSprite对象的代码示例: var t1 :TextFieldSprite = new TextFieldSprite(); t1.setText( "TextFieldSprite 1" ); addChild( t1 ); var t2 :TextFieldSprite = t1.clone() as TextFieldSprite; trace(t2.getText());//TextFieldSprite 1 t2.setText( "TextFieldSprite 2" ); trace(t2.getText());//TextFieldSprite 2 addChild( t2 ); t2.y = t1.height; 实例化一个显示对象数组,这时候便不能使用concat或slice复制数组了,须使用for关键字自行实现复制逻辑,示例如下: var arr1 : Array = [new TextFieldSprite(), new TextFieldSprite()]; var arr2 :Array = new Array(arr1.length); var n :int = arr1.length; for(var j:int=0; j<n; j++) { arr2[j] = arr1[j].clone(); arr2[j].setText( "TextFieldSprite " + j); } arr2.concat(arr1).forEach( function(item :DisplayObject, index :int=-1, arr :Array = null) :void { addChild(item); item.y = index * item.height; } ); for关键字在这里是可以保证遍历所有数组元素的,可以使用。运行效果图如下: 6,使用原型扩展Array每次在拷贝数组时,均使用for循环复制数组元素是一件很麻烦的事情,如果Array本身具有一个clone方法该有多好。AS3作为一门支持prototype的语言,可以在Array上扩展出clone方法,示例代码如下: Array.prototype.clone = function() :Array { var r :Array = new Array(this.length); for(var j:int; j<this.length; j++) { r[j] = this[j].clone(); } return r; }; var arr1 : Array = [new TextFieldSprite(), new TextFieldSprite()]; var arr2 :Array = arr1.clone(); arr2.concat(arr1).forEach( function(item :DisplayObject, index :int=-1, arr :Array = null) :void { addChild(item); item.y = index * item.height; } );
7,AS3中深拷贝最佳实践如果你在使用Gumbo进行项目开发,Adobe在mx.utils.ObjectUtil中提供了两个深拷贝对象的方法: 1) copy 该方法使用ByteArray实现,与前面的clone方法的实现原理一致。该方法可用于深拷贝非复合并且非由Flash Player定义的对象。 2) clone 该方法内嵌了copy方法调用,可用于深拷贝copy不支持的复合对象,但也不能拷贝由Flash Player定义的显示对象。这个方法不能在数字for循环中调用,因为它是耗费用户CPU的操作,使用它要注意节约。 如果你不在使用Gumbo开发,按上面的方法实现ICloneable接口,然后使用for循环复制到新数组元素。使用prototype扩展clone方法并非明智之举! 为什么说使用prototype扩展clone方法并非明智之举? 8,问题1)在AS3中有哪些对象作为数组元素时,是引用类型? 2)为什么说for不能保证遍历数组的所有元素? 3)为什么在AS3中不能使用ByteArray拷贝显示对象?使用它拷贝出来的对象为什么不能转换为DisplayObject? 4)为什么说使用prototype扩展clone方法并非明智之举? |
发表评论
-
合并多个数组
2011-11-30 19:55 5538合并多个数组,可合并一维数组和二维数组,哈哈.比较简单,自己先 ... -
AS3数组学习
2011-11-28 00:19 1031indexOf lastIndexOf 返回 ... -
as3 中判断数组中最大值
2011-11-27 22:55 1956var my_arr:Array=[12,50,80,321, ... -
Flex的array和arrayCollection的应用实例
2011-11-24 19:23 2134ArrayCollection是flex中的数组集合类,它是很 ... -
AS3数组复制
2011-11-24 19:00 1064在actionscrip3.0中是没有提供内置的数组克隆的方法 ... -
array,arraylist,arraycollection
2011-11-24 18:37 797private var dpFlat:ArrayColl ... -
as3中length函数
2011-12-05 21:43 784取xml中元素长度时要用length() 注意哦是 ... -
AS3 数组
2011-11-23 20:22 1407//创建空数组 var arr:Arra ... -
AS3中JSON的基本应用实例
2011-11-15 19:24 702最近发现有不少通过“AS3 json”关键词搜索过来的朋友 ...
相关推荐
javascript中数组深拷贝途径及对象数组深拷贝 什么是浅拷贝 在js当中,我们常常遇到数组复制的的情况,许多人一般都会使用“=”来直接把一个数组赋值给一个变量,如: var a=[1,2,3]; var b=a; console.log(b); ...
本文实例讲述了javascript二维数组和对象的深拷贝与浅拷贝。分享给大家供大家参考,具体如下: 这篇文章主要为大家详细介绍了js实现数组和对象的深浅拷贝, 1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新...
我就废话不多说了,大家还是直接看代码吧~ <div></div> [removed] export default { mounted() { this.init(); ... let lodash = require('lodash');... c: [1, 2, 3], h: () => { return 123; }, k: undefined
下面小编就为大家带来一篇浅谈JavaScript中面向对象的的深拷贝和浅拷贝。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。 1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。 ...
一、数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的...
引用类型(包括数组,对象),按址传递,引用类型在值传递的时候是内存中的地址。 克隆或者拷贝分为2种: 浅度克隆:基本类型为值传递,对象仍为引用传递。 深度克隆:所有元素或属性均完全克隆,并于原引用类型...
答: (1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 (2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局...
在JavaScript这门语言中,数据类型分为两大类:基本数据类型和复杂数据类型。基本数据类型包括Number、Boolean、String、Null、String、Symbol(ES6 新增),而复杂数据类型包括Object,而所有其他引用类型(Array、...
在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性。 字体对象CFont用于输出文字时选用不同风格和大小的字体。可...
本书以流行的面试题讲解为主要内容,介绍了C、C++语言基本概念,包括保留字、字符串、指针和引用、结构体、库函数等各个方面的基础知识,介绍了面向对象编程基本概念,包括如何实现继承、多态和封装等。还介绍了排序...
db2 IBM DB2在企业级的应用最为广泛, 在全球的500家最大的企业中,几乎85%以上用DB2数据库服务器。收费 大型企业 Access 微软 Access是一种桌面数据库,只适合数据量少的应用,在处理少量 数据和单机访问的数据库时...