|
|
Function parameters
ActionScript 3.0 provides some functionality
for function parameters that may seem novel for programmers new
to the language. Although the idea of passing parameters by value
or reference should be familiar to most programmers, the
arguments
object and the ... (rest)parameter may be new to many of you.
Passing arguments by value or by referenceIn many programming languages,
it’s important to understand the distinction between passing arguments
by value or by reference; the distinction can affect the way code
is designed.
To
be passed by value means that the value of the argument is copied
into a local variable for use within the function. To be passed
by reference means that only a reference to the argument is passed
instead of the actual value. No copy of the actual argument is made.
Instead, a reference to the variable passed as an argument is created
and assigned to a local variable for use within the function. As
a reference to a variable outside the function, the local variable
gives you the ability to change the value of the original variable.
In ActionScript 3.0, all arguments
are passed by reference, because all values are stored as objects.
However, objects that belong to the primitive data types, which includes
Boolean, Number, int, uint, and String, have special operators that
make them behave as if they were passed by value. For example, the
following code creates a function named
passPrimitives()
that defines two parameters named
xParam
and
yParam
, both of type int. These parameters are similar to local
variables declared inside the body of the
passPrimitives()
function. When the function is called with the arguments
xValue
and
yValue
, the parameters
xParam
and
yParam
are initialized with references to the int objects represented
by
xValue
and
yValue
. Because the arguments are primitives, they behave as
if passed by value. Although
xParam
and
yParam
initially contain only references to the
xValue
and
yValue
objects, any changes to the variables within the function
body generate new copies of the values in memory.
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
Within the
passPrimitives()
function, the values of
xParam
and
yParam
are incremented, but this does not affect the values of
xValue
and
yValue
, as shown in the last
trace
statement. This would be true even if the parameters were
named identically to the variables,
xValue
and
yValue
, because the
xValue
and
yValue
inside the function would point to new locations in memory
that exist separately from the variables of the same name outside
the function.
All other objects—that is, objects that do not
belong to the primitive data types—are always passed by reference,
which gives you ability to change the value of the original variable.
For example, the following code creates an object named
objVar
with two properties,
x
and
y
. The object is passed as an argument to the
passByRef()
function. Because the object is not a primitive type,
the object is not only passed by reference, but also stays a reference.
This means that changes made to the parameters within the function
will affect the object properties outside the function.
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
The
objParam
parameter references the same object as the global
objVar
variable. As you can see from the
trace
statements in the example, changes to the
x
and
y
properties of the
objParam
object are reflected in the
objVar
object.
Default parameter valuesNew
in ActionScript 3.0 is the ability to declare
default parameter values
for a function. If a call to a function with default parameter
values omits a parameter with default values, the value specified
in the function definition for that parameter is used. All parameters
with default values must be placed at the end of the parameter list.
The values assigned as default values must be compile-time constants.
The existence of a default value for a parameter effectively makes
that parameter an
optional parameter
. A parameter without a default value is considered a
required parameter
.
For example, the following code creates a function with
three parameters, two of which have default values. When the function
is called with only one parameter, the default values for the parameters
are used.
function defaultValues(x:int, y:int = 3, z:int = 5):void
{
trace(x, y, z);
}
defaultValues(1); // 1 3 5
The arguments objectWhen parameters are passed to a function,
you can use the
arguments
object to access information about the parameters passed
to your function. Some important aspects of the
arguments
object include the following:
The
arguments
object is an array that includes all the parameters passed
to the function.
The
arguments.length
property reports the number of parameters passed to the
function.
The
arguments.callee
property provides a reference to the function itself, which
is useful for recursive calls to function expressions.
Note: The
arguments
object is not available if any parameter is named
arguments
or if you use the ... (rest) parameter.
If the
the
arguments
object is referenced in the body of a function, ActionScript
3.0 allows function calls to include more parameters than those
defined in the function definition, but will generate a compiler
error in strict mode if the number of parameters doesn’t match the
number of required parameters (and optionally, any optional parameters).
You can use the array aspect of the
arguments
object to access any parameter passed to the function,
whether or not that parameter is defined in the function definition.
The following example, which only compiles in standard mode, uses
the
arguments
array along with the
arguments.length
property to trace all the parameters passed to the
traceArgArray()
function:
function traceArgArray(x:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 1
// 2
// 3
The
arguments.callee
property is often used in anonymous functions to create
recursion. You can use it to add flexibility to your code. If the
name of a recursive function changes over the course of your development
cycle, you need not worry about changing the recursive call in your
function body if you use
arguments.callee
instead of the function name. The
arguments.callee
property is used in the following function expression to
enable recursion:
var factorial:Function = function (x:uint)
{
if(x == 0)
{
return 1;
}
else
{
return (x * arguments.callee(x - 1));
}
}
trace(factorial(5)); // 120
If you use the ... (rest) parameter in your function
declaration, the
arguments
object will not be available to you. Instead, you must
access the parameters using the parameter names that you declared
for them.
You should also be careful to avoid using the string
"arguments"
as a parameter name, because it will shadow the
arguments
object. For example, if the function
traceArgArray()
is rewritten so that an
arguments
parameter is added, the references to
arguments
in the function body refer to the parameter rather than
the
arguments
object. The following code produces no output:
function traceArgArray(x:int, arguments:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
traceArgArray(1, 2, 3);
// no output
The
arguments
object in previous versions of ActionScript also contained
a property named
caller
, which is a reference to the function that called the current
function. The
caller
property is not present in ActionScript 3.0, but if you
need a reference to the calling function, you can alter the calling
function so that it passes an extra parameter that is a reference
to itself.
The ... (rest) parameterActionScript
3.0 introduces a new parameter declaration called the ... (rest) parameter.
This parameter allows you to specify an array parameter that accepts any
number of comma- delimited arguments. The parameter can have any
name that is not a reserved word. This parameter declaration must
be the last parameter specified. Use of this parameter makes the
arguments
object unavailable. Although the ... (rest) parameter
gives you the same functionality as the
arguments
array and
arguments.length
property, it does not provide functionality similar to
that provided by
arguments.callee
. You should ensure that you do not need to use
arguments.callee
before using the ... (rest) parameter.
The following
example rewrites the
traceArgArray()
function using the ... (rest) parameter instead of the
arguments
object:
function traceArgArray(... args):void
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 1
// 2
// 3
The ... (rest) parameter can also be used with other
parameters, as long as it is the last parameter listed. The following
example modifies the
traceArgArray()
function so that its first parameter,
x
, is of type int, and the second parameter uses the ...
(rest) parameter. The output skips the first value, because the
first parameter is no longer part of the array created by the ...
(rest) parameter.
function traceArgArray(x: int, ... args)
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 2
// 3
|