as3中属性访问原理(转)

转自http://www.laaan.cn/?p=1493

今天写代码,发现一个问题:

 
   
  1. package   
  2. {  
  3.     public class B   
  4.         {  
  5.         //私有属性  
  6.         private var doo:String = "abc";  
  7.    
  8.         public function test(target:B):*   
  9.                {  
  10.             return target.doo;  
  11.         }  
  12.    
  13.     }  
  14. }  

然后我在另一个类里面,这样操作:

var value = new B().test(new B());
trace(value);

竟然能输出B实例的私有变量doo。doo这个变量所在的namespace应该是当前实例中——也就是说是有当前实例中才能访问该属性。但是很不幸,测试证明在其他B的实例中也能访问。于是想到as3中属性访问的原理:MultiName。
在as3中,访问属性是通过MultiName来实现的。最基本的情况这样的:MultiName包含两个数据段,一个是name,一个namespace。当你访问一个对象的属性时,会通过name来查找该对象的属性,如果该属性名等于name,而且该属性的namespace和MultiName中的namespace也相等的话,就认为该属性就是该MultiName要访问的属性了。
我看了下swf的结构,在B类的test方法中,target.doo编译后生成的指令中,访问属性doo的MultiName中的namespace和B类中属性doo的namesapce相同。这样的话,上面这个例子就可以理解了。

接下来,我做了一个测试:

//在别类中,直接新建一个B实例,直接访问doo1。通过非严格模式编译
var b:B = new B();
trace(b.doo);

运行的结果当然会报找不到doo属性的错误。因为b.doo编译后所生成的查找doo的MultiName中所包含的namespace和和B类中doo属性的namespace不相等(name数据是相等的)。于是我将B类中doo属性的namespace直接注入到查找doo的MultiName中去。然后重新组合swf——整个世界终于清静了。

既然原理确实是这样的,我就想到是不是可以提供一个方法专门用来访问对象的私有属性呢,比如:

function getPrivate(obj:*, pro:String):*
 {
	return obj[pro];
}

这个想法纠结了我一个下午,最后的结论是:不可能——至少我没想到有方法可以的。主要原始是:私有属性的namespace必须是和查找MultiName中的namespace在内存中的地址一样才能访问——我尝试保持数据一样但是内存地址不一样,失败了。

联想到一个动态属性访问的问题。动态访问属性时所使用的MultiName,不包含namespace数据段,但是有一个namespace set数据段,里面包含当前域能访问的所有namespace。这样,在查找属性时,得来一个循环来比对,会消耗更多的资源。

转载于:https://www.cnblogs.com/qiance/archive/2010/08/22/1805724.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值