as3的Proxy类二三事
sshong 发表于2009年11月19日 17:31:00 更新于2009年11月19日 17:43:00
Proxy类,存在于flash.utils包下。

API介绍中称:
The Proxy class lets you override the default behavior of ActionScript operations (such as retrieving and modifying properties) on an object。
The Proxy class is a replacement for theand Object.addProperty features of ActionScript 2.0, which are no longer available in ActionScript 3.0. The Object.addProperty() feature allowed you to dynamically create get and set methods in ActionScript 2.0. Although ActionScript 3.0 provides get and set methods at compile time, you cannot dynamically assign one to an object unless you use the Proxy class.

也就是说Proxy类对象可以动态创建方法,同时可以覆盖ActionScript的如获取、修改属性的默认行为。

首先研究下Proxy类的几个待覆盖的方法。

callProperty(name:*, ... rest):*
覆盖可作为函数调用的对象属性的行为。

deleteProperty(name:*):Boolean
覆盖删除属性的请求。

getDescendants(name:*):*
覆盖 descendant 运算符的使用。

getProperty(name:*):*
覆盖对属性值的任何请求。

hasProperty(name:*):Boolean
覆盖请求以按名称来检查对象是否具有特定属性。

isAttribute(name:*):Boolean
检查是否还将提供的 QName 标记为属性。

nextName(index:int):String
允许按索引编号枚举代理对象的属性以检索属性名称。

nextNameIndex(index:int):int
允许按索引编号枚举代理对象的属性。

nextValue(index:int):*
允许按索引编号枚举代理对象的属性以检索属性值。

setProperty(name:*, value:*):void
覆盖更改属性值的调用。

其中nextName用于表达式for(var p:String in obj)
nextValue用于表达式for each(var o:Object in obj)

而nextNameIndex则是这两个表达式的核心所在,两个表达式均以index从0开头,并传入nextNameIndex中计算,将计算的结果index分别传入nextName或者nextValue,直到nextNameIndex计算的结果为0,循环结束。
可以通过一个实例验证

package
{
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;
   
    use namespace flash_proxy;
   
    public dynamic class MyProxy extends Proxy
    {
        private var _properties:Object = {};
       
        flash_proxy override function callProperty(name:*, ... rest):*
        {
            if(_properties[name] == undefined)
            {
                _properties[name] = traces;
            }
            rest.unshift(name);
            traces(rest);
            return _properties[name];
        }
        flash_proxy override function getProperty(name:*):*
        {
            return _properties[name];
        }
        private var _pnames:Array;
        flash_proxy override function nextNameIndex(index:int):int
        {
            trace("nextNameIndex", index);
            if(index == 0)
            {
                _pnames = [];
                for(var pname:String in _properties)
                {
                    _pnames.push(pname);
                }
            }
            return (index<_pnames.length) ? index+1 : 0;
        }
        flash_proxy override function nextName(index:int):String
        {
            //trace("nextName", index);
            return _pnames[index-1];
        }
        flash_proxy override function nextValue(index:int):*
        {
            //trace("nextValue", index);
            return _properties[_pnames[index-1]];
        }
        private function traces(...args):void
        {
            trace(args);
        }
    }
}

var obj:MyProxy = new MyProxy();
obj.testFunc1("hi1");
obj.testFunc2("hi2");

for(var p:String in obj)
{
    trace(p, obj[p]);
}
for each(var o in obj)
{
    trace(o);
}

输出为:
testFunc1,hi1
testFunc2,hi2

nextNameIndex 0
testFunc1 function Function() {}
nextNameIndex 1
testFunc2 function Function() {}
nextNameIndex 2

nextNameIndex 0
function Function() {}
nextNameIndex 1
function Function() {}
nextNameIndex 2


可能通过这个例子有些人觉得这个没什么意义,因为似乎动态创建方法如果用Object也可以实现同样的功能。

譬如:
var obj:Object = {};
obj.testFunc1 = obj.testFunc2 = function(str:String){trace(str);}
obj.testFunc1("hi1");
obj.testFunc2("hi2");

我的理解是,Proxy类通过统一覆盖callProperty(name:*, ... rest):* 方法,能自动获取动态生成的方法名称name,可以根据name(方法名)和rest一次处理所有动态创建的方法(如生成某个新对象),特别适合于有许多相同特性的不定方法的类,如本地操作(Remoting)对应服务端的类方法(如AMFPHP端某个类,要动态生成的方法也就是对应的该类的方法)。

而object则不行,object无法动态知晓要动态创建的方法的名称,只能手工为object动态创建某固定名称的方法,而且无法覆盖ActionScript的如获取、修改属性的默认行为。
标签:as3ProxyObject分类:As3&Flex阅读:5455
评论
暂无评论
添加评论
您的大名,限长10汉字,20英文(*)
电子信箱(*)
您的网站
正文,限长500汉字,1000英文(*)
验证码(*) 单击刷新验证码
联系我
博客订阅