作者的blog:www.kingda.org
function究竟是什么?
我们习惯了function的存在,就像习惯了我们呼吸的空气却不去探究它的本质。看起来,似乎function和number, boolean, string一样都是actionscript本来就有的类型。
先看以下代码:
trace (afunc); //输出:[type function]
trace (afunc instanceof function); //输出:true
trace (afunc instanceof object); //输出:true
function afunc() {
trace (“this is afunc!excuted!”);
}
第一行告诉我们afunc的类型是function, 第二行又证实了这一点afunc确实是一个function类型的实例,第三行更加有意思告诉我们afunc是一个object。
初学者可能很惊奇,其实as2.0中除了原始数据类型number, boolean, string,undefined, null,其余全是object. 而as3.0中则更加极端,一切皆对象。包括原始数据类型也是object,只不过是特殊的不变对象(immutable objects)类型。与主题扯远了,打住。
function本质上到底是怎样的一种object?
与其他编程语言不同,在as中, function是一个object,可以有独立的属性甚至方法。比如arguments,callee,caller。在as3.0中,function还由更多的属性。
函数一旦执行,一个特殊的对象就建立了。我们称它为"active object",它含有以上的属性和本地变量。这个对象我们是不可访问的,属于内建的机制。同时,每个function都含有一个内置的范围链(scope chain),这时也将被建立,以使flash player来检查所有的声明。函数可以层层嵌套,范围链也是如此。最大的范围链那当然是global函数的范围链了,包括所有的全局变量和函数。
知道了function 是object又怎样?
会给我们带来极大的便利和编程思维的改变:
运用一:这是简单运用, 设立一个代理函数对象,根据条件的不同,将它指向不同的函数,实现动态改变。相信有经验的程序员都了解动态改变函数的便利性。而且由于as提供了这种便利,运用这个特性可以衍生大量技巧。
var kingdafunc:function;
var sex:string = "male";
if ( sex == "male") {
kingdafunc = malefunc;
} else {
kingdafunc = femailfunc;
}
kingdafunc(); //输出: i am a boy
function malefunc() {
trace ("i am a boy");
}
function femalefunc() {
trace ("i am a girl");
}
运用二:建立函数执行队列。
比如说,我有一个对象,我想根据不同的情况对它进行一系列的操作。但是有时需要所有的操作,有时又只需要一部分的操作。那么这个较高级的技巧,就能保证代码的高度重用性和简洁。
var funcary:array = new array();
//将需要的操作步骤加入队列
funcary.push(afunc);
funcary.push(bfunc);
funcary.push(cfunc);
//供操作的对象
var originobject:object = new object();
//需要执行几步由execqueue这个参数决定,在实际工程运用中这个数可能是动态决定的。
var execqueue:number = funcary.length;
/核心步骤:/函数队列执行。实际运用中可以把它包装成一个函数,或者一个类的实例。
for (var i:number =0; i<execqueue; i++) {
funcary[i](originobject);
}
//trace出执行操作后的originobject里面的内容
for (var i in originobject) {
trace ( i + ":" + originobject[i]);
}
//操作步骤a,b,c
function afunc(eo:object) {
eo.afuncexected = true;
trace ("afunc()");
}
function bfunc(eo:object) {
eo.bfuncexected = true;
trace ("bfunc()");
}
function cfunc(eo:object) {
eo.cfuncexected = true;
trace ("cfunc()");
}
输出内容为:
afunc()
bfunc()
cfunc()
cfuncexected:true
bfuncexected:true
afuncexected:true
前三行表明a,b,c三个函数按顺序执行了。后三行表明orginobject确实经过了三步操作,多了三个为true的属性。
黑羽提醒:技巧可以再延深!
可以通过一个函数来管理队列里面各个元素的位置,达到改变操作函数的顺序。比如通过一个数组来安排调用顺序
var operationary:array = [2,1,0]
for(var i:number = 0; i<operationary.length; i ++) {
funcary[operationary[i]](originobject);
}
这样函数就通过2,1,0这样的倒序来执行操作。
这个技巧还有很多可以延伸的地方,比如说动态控制操作函数的参数等等,供大家自己研究扩展。
经典论坛讨论帖:
http://www.blueidea.com/bbs/newsdetail.asp?id=2610583
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器