参与本文讨论:闪吧本文讨论帖
2.8 对函数变量的引用
2.8.1 函数是什么? 如同我在2.1说过的一样,函数也是 object,我们对函数的使用也是通过引用实现的:
trace ( function(){} instanceof Object )
结果是true 不过 typeof( function(){} ) 返回的是更加详细的分类:"function"
我们这样定义一个函数:
function( 参数1 , 参数2 ,.... ,参数N ) {
//执行语句
return <返回参数>
}
比如: function( x,y ){ trace(x+y) } 但是与一般的object类似, 你一般需要用变量保存函数的引用,否则函数也会消失在虚无之中,所以我们一般是这样的: addNum = function(x , y) {trace(x+y)};
用法:
addNum( 10,14 );
结果是24。
既然是引用,你当然可以复制引用和删除变量了:
addNum2 = addNum;
delete (addNum);
addNum(100, 200);
addNum2( 1, -10);
addNum被删掉之后, addNum(100,200) 由于addNum不是函数所以结果是 null
而addNum2仍然保留原来函数的引用,结果是 -9
2.8.2 函数定义方法的差别: 函数有两种定义方法,比如如下的例子:
//方法1: 预定义:
function a() { trace("preDefine"); };
//方法2: 动态生成然后传参:
a = function(){ trace("dynamicDefine, andPressRefence")}
方法1 和方法2 区别很大:
方法1 属于预处理, 是在mc初始化的时候运行的,而在正常运行期间不执行。也就是说,在1个object的生命周期之中,方法1只会执行一次:
t = getTimer();
for(var i = 0; i<10000; i++){
a = 1;
function a(){
trace("this is a function");
}
}
trace("time used:" + (getTimer()-t) );
trace("a=" + a);
a();
我的机器上的结果是: time used:182
a=1 速度很快,trace(a)的结果是 1 而a()并没有显示任何东西。
为什么呢?上述的as分为两段执行:初始化的时候执行:
a = function (){
trace("this is a function);
}
而运行时候执行:
t = getTimer();
for(var i = 0; i<10000; i++){
a = 1;
}
trace(" time used:" + getTimer()-t );
trace(a);
a();
方法2 和一般的变量定义是一样的,首先创建一个函数对象,然后再把他的引用传给变量。所以运行如下代码:
t = getTimer();
for(var i = 0; i<10000; i++){
a = 1;
a = function (){
trace("this is a function");
}
}
trace("time used:" + (getTimer()-t));
trace("a="+a);
a();
句段 a= function(){ .....} 需要执行10000 次。运行比1慢得多,结果是: time used:821
a=[type Function]
this is a function
2.8.3 活用函数特性: 由于调用一个不存在的函数结果是 null ,所以我们往往用函数作接口,比如 MovieClip.onEnterFrame 函数 如果某个mc的onEnterFrame存在的话,系统就会在每帧的时候调用该函数。 你看看下面这个小把戏: 偷梁换柱~~~
我们可以用这样一个技巧,在某些函数外部加一些东西而不需要了解函数的代码~~ 比如,假如当前有很多mc 覆盖了onEnterFrame函数,我们可以这样了解那些在_root下的mc 的onEnterFrame函数是以什么顺序执行的
for(var i in _root){
if(_root[i].onEnterFrame != null){ //如果这个Object实现了onEnterFrame接口的话
_root[i].oldFunc = _root[i].onEnterFrame;//首先保存原来的onEnterFrame的句柄
_root[i].onEnterFrame = function(){//然后开始替换了~~加上一层壳~~
trace(this+ ": onEnterFrame Called.");
this.oldFunc();//我们用保留的句柄调用原来的函数
trace(this+ ": onEnterFrame Returned.");
}
}
}
如果要取消这些附加的操作
for(var i in _root){
if(_root[i].oldFunc!= null){//如果发现改过得痕迹
_root[i].onEnterFrame = _root[i].oldFunc;
delete(oldFunc);
}
}
我那个震动函数就是用这种方法作的。 关于函数的具体用法和说明,我以后在函数部分和oop部分会详细解释