as3学习笔记(四)函数

.函数基础

as3中两种函数定义方式,函数语句和函数表达式

函数语句:

function myTest(aParam:String):void
{
         trace(aPamram);
}

函数表达式:

var myTest:Function = function(aParam:String):void
{
         trace(aParam);
}

一个重要区别:函数语句存在于定义它们的整个作用域(包括出现在该函数语句前面的语句)内。与之相反,函数表达式只是为后续的语句定义的。例如,下面的代码能够在定义 scopeTest() 函数之前成功调用它:

statementTest(); // statementTest
function statementTest():void
{
    trace(
"statementTest");
}

函数表达式只有在定义之后才可用,因此,下面的代码会生成运行时错误:

expressionTest(); // 运行时错误
var expressionTest:Function = function ()
{
    trace(
"expressionTest");
}

官方建议:多用函数语句,尽量少用函数表达式。

 

.嵌套函数

顾名思义,函数里嵌套函数:

function getNameAndVersion():String
{
    
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

function foo():Function
{
    
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里面规定,属于基元数据类型(包括 BooleanNumberintuint String)的对象表现为按值传递,剩下的对象按引用传递(传址)。

(注:在as3中,所有的参数本质上均是按引用传递的,因为所有的值都存储为对象。它之所以把基元数据类型表现为传值的特性,应该是考虑到大部分程

序员的习惯问题。这就像javaC#里面把本来是对象的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 中新增了为函数声明“默认参数值”的功能。调用函数可以不传递声明为“默认参数值”的参数,没有默认值的参数被视为“必需的参数”。

例如,下面的代码创建一个具有三个参数的函数,其中第一个参数是必需参数,后两个参数具有默认值。当仅用一个参数调用该函数时,后两个参数将使用默认值。

function defaultValues(x:int, y:int = 3, z:int = 5):void
{
     trace(x, y, z);
}
defaultValues(
1); // 1 3 5

 

arguments 对象

在将参数传递给某个函数时,可以使用 arguments 对象来访问有关传递给该函数的参数的信息。arguments 对象的一些重要方面包括:

arguments 对象是一个数组,其中包括传递给函数的所有参数。

arguments.length 属性报告传递给函数的参数数量。

arguments.callee 属性提供对函数本身的引用,该引用可用于递归调用函数表达式。

 

...(rest) 参数

ActionScript 3.0 中引入了一个称为 ...(rest) 参数的新参数声明。用来指定一个数组参数以接受任意多个以逗号分隔的参数。此参数可以拥有保留字以外的任意名称:

function traceArgArray(x: int args)
{
    
for (var i:uint = 0; i < args.length; i++)
    {
        trace(args[i]);
    }
}

traceArgArray(
123);

// 输出:
//
 2
//
 3

 

.函数本质

as3中,函数本质上是对象,可以它可以作为参数传递给另一个函数,还可以附加上属性和方法。

例如:clickListener() 的函数作为参数传递给 addEventListener() 方法

addEventListener(MouseEvent.CLICK, clickListener);//clickListener()作为参数,要去掉小括号

 

函数作为对象,其固有一个属性length,表明其参数数量。这里可以比较下它与arguments.length 的不同。

function traceLength(x:uint, y:uint):void
{
    trace(
"arguments received: " + arguments.length);
    trace(
"arguments expected: " + traceLength.length);
}

traceLength(
35711);

// 输出:
//
arguments received:4
//
arguments expected:2 

可以看出,arguments.length表明传递给函数的参数个数,函数名.length表明函数声明的参数个数。

posted @ 2009-08-07 16:46  MichaelChen  阅读(1158)  评论(1编辑  收藏  举报