as3学习笔记(四)函数
一.函数基础
as3中两种函数定义方式,函数语句和函数表达式
函数语句:
{
trace(aPamram);
}
函数表达式:
{
trace(aParam);
}
一个重要区别:函数语句存在于定义它们的整个作用域(包括出现在该函数语句前面的语句)内。与之相反,函数表达式只是为后续的语句定义的。例如,下面的代码能够在定义 scopeTest() 函数之前成功调用它:
function statementTest():void
{
trace("statementTest");
}
函数表达式只有在定义之后才可用,因此,下面的代码会生成运行时错误:
var expressionTest:Function = function ()
{
trace("expressionTest");
}
官方建议:多用函数语句,尽量少用函数表达式。
二.嵌套函数
顾名思义,函数里嵌套函数:
{
function getVersion():String
{
return "9";
}
function getProductName():String
{
return "Flash Player";
}
return (getProductName() + " " + getVersion());
}
trace(getNameAndVersion()); // Flash Player 9
在将嵌套函数传递给外部代码时,它们将作为函数闭包传递,这意味着嵌套函数保留在定义
该函数时处于作用域内的任何定义,这就是“函数闭包”:
例如,下面的代码创建两个函数:foo() (返回一个用来计算矩形面积的嵌套函数rectArea())和 bar() (调用 foo() 并将返回的函数闭包存储在名为 myProduct 的变量中)。即使 bar() 函数定义了自己的局部变量 x (值为 2),当调用函数闭包 myProduct()时,该函数闭包仍保留在函数 foo() 中定义的变量 x (值为 40)。因此, bar() 函数将返回值 160,而不是 8。
{
var x:int = 40;
function rectArea(y:int):int // 定义函数闭包
{
return x * y
}
return rectArea;
}
function bar():void
{
var x:int = 2;
var y:int = 4;
var myProduct:Function = foo();
trace(myProduct(4)); // 调用函数闭包
}
bar(); // 160
三.函数参数
关于什么是参数的传值和传址(或者叫按引用传递),应该不用多说了,连这都不知道的请面壁。
as3里面规定,属于基元数据类型(包括 Boolean、Number、int、uint 和 String)的对象表现为按值传递,剩下的对象按引用传递(传址)。
(注:在as3中,所有的参数本质上均是按引用传递的,因为所有的值都存储为对象。它之所以把基元数据类型表现为传值的特性,应该是考虑到大部分程
序员的习惯问题。这就像java和C#里面把本来是对象的string展现成按值传递。)
例子:
function passPrimitives(xParam:int, yParam:int):void
{
xParam++;
yParam++;
trace(xParam, yParam);
}
var xValue:int = 10;
var yValue:int = 15;
trace(xValue, yValue); // 10 15
passPrimitives(xValue, yValue); // 11 16
trace(xValue, yValue); // 10 15
//引用传递,改变原值
function passByRef(objParam:Object):void
{
objParam.x++;
objParam.y++;
trace(objParam.x, objParam.y);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar); // 11 16
trace(objVar.x, objVar.y); // 11 16
ActionScript 3.0 中新增了为函数声明“默认参数值”的功能。调用函数可以不传递声明为“默认参数值”的参数,没有默认值的参数被视为“必需的参数”。
例如,下面的代码创建一个具有三个参数的函数,其中第一个参数是必需参数,后两个参数具有默认值。当仅用一个参数调用该函数时,后两个参数将使用默认值。
{
trace(x, y, z);
}
defaultValues(1); // 1 3 5
arguments 对象
在将参数传递给某个函数时,可以使用 arguments 对象来访问有关传递给该函数的参数的信息。arguments 对象的一些重要方面包括:
arguments 对象是一个数组,其中包括传递给函数的所有参数。
arguments.length 属性报告传递给函数的参数数量。
arguments.callee 属性提供对函数本身的引用,该引用可用于递归调用函数表达式。
...(rest) 参数
ActionScript 3.0 中引入了一个称为 ...(rest) 参数的新参数声明。用来指定一个数组参数以接受任意多个以逗号分隔的参数。此参数可以拥有保留字以外的任意名称:
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
// 输出:
// 2
// 3
四.函数本质
as3中,函数本质上是对象,可以它可以作为参数传递给另一个函数,还可以附加上属性和方法。
例如:clickListener() 的函数作为参数传递给 addEventListener() 方法
addEventListener(MouseEvent.CLICK, clickListener);//clickListener()作为参数,要去掉小括号
函数作为对象,其固有一个属性length,表明其参数数量。这里可以比较下它与arguments.length 的不同。
{
trace("arguments received: " + arguments.length);
trace("arguments expected: " + traceLength.length);
}
traceLength(3, 5, 7, 11);
// 输出:
//arguments received:4
//arguments expected:2
可以看出,arguments.length表明传递给函数的参数个数,函数名.length表明函数声明的参数个数。