函数是在程序中可以重复使用的代码. 你可以将需要处理的值或对象通过参数的形式传递给函数, 然后由函数得到结果. 从另一个角度说, 函数存在目的就是为了简化编程的负担, 减小代码量和提高效率. 而一个写得好的函数, 就像一个"黑箱", 你只要懂得调用它就行了, 而不用去关心它的详细功能是如何实现的 创建自己的函数---函数定义(Definition) 要创建一个函数, 就需要有函数的定义. 对于 Actions cript, 就没有什么返回值类型, 形参实参之类的东西好讨论了. 下面是一个简朴函数的定义: //计算矩形面积的函数 function areaOfBox(a, b) { return a*b; //在这里返回结果 } //测试函数 area = areaOfBox(3, 6); trace("area="+area); 现在来分析一下函数定义的结构. function 要害字说明这是一个函数定义, 而不是一段执行代码. 其后便是函数的名称: areaOfBox. 函数名后面的括号内是函数的参数列表(也可以没有参数, 但括号是必须要有的). 紧接着的大括号内是函数的实现代码, 即 Actions cript 语句. 假如函数需要返回值, 可以使用 return 要害字加上要返回的变量名, 表达式或常量名. 在一个函数中可以有多个 return 语句, 但无论何时, 只要执行了其中的任何一个 return 后, 函数便自行终止而不会继承执行下去. 假如没有 return 语句, 则在函数尾最后一个语句执行后结束. 因为 Actions cript 的特别性, 函数的参数定义并不要求参数类型的声明, 即可以不指定参数类型. 这省去了很多麻烦, 也带来了一些问题. 虽然把上例中倒数第二行改为 area = areaOfBox("3", 6); 也同样可以得到 18 的结果, 但是这对程序的稳定性异常不利(如果函数里面用到了 a+b 的话, 就会变成字符串的连接运算, 结果自然会出错). 所以, 有时候在函数中类型检查是不可少的. 在函数体中参变量用来代表要操作的对象. 你在函数中对参变量的操作, 就是对传递给函数的参数的操作. 上例中的 a*b 在你调用函数时会被转化为参数的实际值 3*6 处理. -------------------------------------------------------------------------------- 函数还有一种创建方式, 叫做函数显式声明(function literal, 不是通过正式的函数声明而是在一个表达式内通过未命名的函数来进行声明): areaOfBox = function(a,b) {return a*b;}; trace("area="+areaOfBox(2,3)); 这种形式的声明常常用在对象的方式或是函数库的函数声明中. 在 Flash MX 的帮助中函数定义部分关于这种声明的范例代码有误, 请注重. -------------------------------------------------------------------------------- 上面是有返回值的函数, 在函数尾使用了 return 要害字来返回结果. 函数也可以不返回任何值. 如下例: //无返回值的函数 function areaOfBox(a, b) { _root.area = a*b; } //测试函数 areaOfBox(3, 6); trace("area="+_root.area); 它的结果也是 18, 只不过最后的结果是传递到 _root 下的指定变量 area 而已.下面一个例子更简朴: //计算矩形面积的函数 function simpleFunc() { trace ("什么都没有"); //在这里返回结果 } //测试函数 simpleFunc(); 最后的输出就是 trace 中的字符串. 就是说, 函数可以既没有参数也没有返回值, 而是一系列操作的集合. 可见函数的使用具有很高的灵活性. -------------------------------------------------------------------------------- 同变量相同, 函数也可以具有全局性. 只要在声明时在前面给它加一个 _global 就可以了: //计算矩形面积的全局函数 _global.areaOfBox = function (a, b) { return a*b; //在这里返回结果 } //测试函数 area = areaOfBox(3, 6); trace("area="+area); 请注重: 在函数体中出现的要害字 this 代表的是调用函数的 MovieClip, 而不是函数体所在的 MovieClip. 这很轻易被忽略而产生不期望的结果. 假如要指定 this 所代表的对象就要用到 Function.call() 和 Function.apply() 方式. 在后面的 arguments 对象介绍中会讲到. 函数参数的检查 为了保证函数运行的准确性, 我们有时必须检测用户是否给了足够的或是准确类型的参数. 下面是我对上面例子进行改动后的代码: //计算矩形面积的全局函数 _global.areaOfBox = function (a, b) { //输出两个参数之和, 用于理解下面的 typeof 语句 trace("a+b="+(a+b)); //检测参数是否足够且类型准确 if(a==undefined || b==undefined || typeof(a+b)!="number") { trace("<参数错误>"); return 0; //返回 0 作为错误时的结果 } return a*b; //在这里返回结果 } //测试函数 trace("----下面是准确的参数----"); area = areaOfBox(3, 6); trace("area="+area); trace("----下面是错误的参数----"); //这里为了节省篇幅, 我在命令中直接调用函数, 而不是先将返回值赋给一个变量 //其实这才是我们常用的函数调用方式 trace("area="+ areaOfBox(3, "6")); trace("----下面是不足的参数----"); trace("area="+areaOfBox(3)); 上例中我用 a==undefined 来判定 a 是否被赋值了(即是否已定义, 对于 undefined 数据类型的内容请参阅前一章的内容). 为了确保万无一失, 我还用了 b==undefined 来保证 b 也已被赋值, 中间使用一个逻辑 "或" 运算符 || 来连接这两个条件. 此外, 在这两个条件后面我又通过 typeof(a+b)!="number" 来确认参数类型是否准确(关于 typeof 要害字的信息请参考前一章). 这里我利用了 Actions cript 的一个特点: 数值与字符串相加的和会被优先做为字符串处理. 所以 a+b 中只要有一个为字符串, 那么整个 a+b 的返回值就是一个字符串, 在后面通过 typeof 来检测的结果自然就不是我们所要的 "number". 通过 trace("a+b="+(a+b)); 输出的结果可以看出这一点. -------------------------------------------------------------------------------- 在 Actions cript 中除了用户定义的函数外, 还有预定义的内建函数. 对于不同的对象, 也有不同的函数(或者说是方式)可以调用. 下面是拥有最高优先级的系统内建函数列表: 函数 说明 Boolean 将所给参数值转化为逻辑值(也叫做布尔值) escape 将所给参数转化为字符串并用 URL 格式编码(所有非标准字符将被转化为以 % 开头的十六进制值) eval 返回所给参数表示的对象, 参数可以是常量, 表达式, 属性等(这在 DuplicateMovieClip 时常常用到) getProperty 返回指定对象的指定属性值 getTimer 返回从动画开始运行到当前所经过的毫秒数 getVersion 返回 Flash 版本和操作系统信息 isFinite 返回所给参数是否是有穷的(逻辑型返回值) //创建新对象 object_1 = new Object(); object_1.value = 0; //为对象加入 value 属性并给予初值 0 object_2 = object_1; //由 object_1 复制出一个 object_2, 此时两者的 value 属性均为 0 <!-- / message --><!-- sig --> //测试函数 areaOfBox.call(object_1, 3, 6); trace("object_1.value="+object_1.value); array_ab = [4, 5]; //创建参数数组 areaOfBox.apply(object_2, array_ab); trace("object_2.value="+object_2.value); 为什么要通过 call 和 apply 来调用函数? 这样不比前面的直接调用麻烦吗? 的确, 这样调用函数比较麻烦, 但你注重到了我使用的第一个参数没有? 通过第一个参数可以指定在函数体中的 this 要害字代表什么对象, 这就是用 call 和 apply 的好处(关于对象和 this 的内容在后面章节中才会提到, 在这里暂且不提). 这个好处只有在实际的编程中你才能体会得到, 这里只是简要介绍一下, 让你有个基本的概念. 假如函数中没有使用 this 要害字, 第一个参数要用 null 代替. 在本例中第一个返回值被放入 object_1 的 value 属性中, 另一个会被放入 object_2 的 value 属性中. 通过 call 和 apply 的第一个参数我们让函数体中的 this 先后代表了 object_1 和 object_2 两个对象. 第一个参数后面的实际参数的给予完全依照要调用函数的参数个数和类型确定. 至于 call 与 apply 的不同之处上面已经表示得很明白了: apply 的实际参数是通过数组传递的. arguments 对象 arguments 对象 arguments 对象, 顾名思义就是参数对象, 它包含的是函数调用的参数. 作为一个数组对象, 它只有三个属性: 属性 描述 arguments.callee 正被调用的函数 arguments.caller 正在进行此调用的函数 arguments.length 传递给被调用函数的参数数目 |
来源: 闪吧 |