In ActionScript, functions are technically a special type of built-in object. The Function class, formally exposed to ActionScript in Flash Player 6 and documented in the ActionScript Language Reference, creates individual function objects. Let's see what that means and how it affects what you can do with functions.
We can use any function as an argument to another function, like this:
function1(function2);
Note that if there are no parentheses following function2, the interpreter doesn't execute function2 but instead just passes its "object reference" as an argument to function1. That is, function1 receives a reference to function2 itself, not the return value of function2( ). Because objects are passed by reference, we can pass a function identifier to another function and it will arrive unscathed. The passed function can be executed like this:
function doCommand (command) { command( ); // Executes the passed function } // Some examples: doCommand(stop); // Pass the built-in stop( ) function (stops current movie) doCommand(play); // Pass the built-in play( ) function (plays current movie)
We can use this technique to assign a callback function to a series of text field objects:
function initFormFields (fields, callbackFunc) { // Set focus callback functions for text fields. for (var i = 0; i < fields.length; i++) { fields[i].onSetFocus = callbackFunc; } } // Create a list of the text fields. editFields = [firstNameField, lastNameField, emailField, phoneField, companyField, commentsField]; // Function that colors a text field blue. function handleFieldFocus ( ) { this.background = true; this.backgroundColor = 0x333399; } initFormFields(editFields, highlightField);
Because functions are a type of object, we can treat them as we treat any other data. In the following example, we assign the built-in gotoAndPlay function to the variable gp, which gives us a shorter way to refer to the function:
var gp = gotoAndPlay; // Create a shortcut reference to gotoAndPlay gp(25); // Invoke gotoAndPlay( ) using our reference
Note again the omission of the parentheses after gotoAndPlay in the first line of the example. As we'll see in Chapter 10 and Chapter 12, functions are commonly stored in object properties to create event handlers and methods.
In addition to passing and storing functions as objects, we can exploit the "objectness" of functions by attaching properties to them, like this:
// Create a function function myFunction () { trace(myFunction.x); } // Attach a property to it myFunction.x = 15; // Check the property value by invoking the function myFunction(); // Displays: 15
|
Function properties offer the benefits of local variables without expiring between function invocations. This is useful when a function needs to be invoked with a unique identifier. Using function properties allows the function to maintain state. Although a function typically "forgets" everything that happened in previous invocations, function properties allow the function to "remember" what happened previously. This is most useful when you want to keep track of how many times an operation has been performed. Here, for example, is a generic function that duplicates a movie clip and gives the duplicated clip a unique name and level by remembering how many clips we've already assigned in the makeClip.count variable:
makeClip.count = 0; // Define a property of makeClip( ) (remember that // makeClip( ) already exists because functions are // defined before code runs) // Duplicate a passed clip and assign the new clip an automatic name function makeClip (theClip) { // Add one to our clip counter makeClip.count++ // The previous line can be written more portably as: // arguments.callee.count++ // Now duplicate the clip, assigning it a unique name and depth theClip.duplicateMovieClip(theClip._name + makeClip.count, makeClip.count); } makeClip(square); // Make a duplicate of square using makeClip( ) square1._x += 100; // Now move the duplicated square to the right
A variable that maintains its value between function invocations is called a static variable in some languages, such as C. Static variables should not to be confused with so-called static functions in C, in which the word static denotes "private." Note that we initialize the makeClip.count variable to 0 once at the start of our script, but it is not reset (reinitialized) every time the function is called. As a general rule, function properties should be used only to store information that pertains to the function. More general information should be stored either in a class or as a global variable.
ActionScript functions can also have other functions attached to them, which can be used to simulate Java-style static class methods. For example:
function SomeClass ( ) { // Constructor code goes here. } SomeClass.staticMethod = function ( ) { // Static method code goes here. }
where SomeClass is the name of the class and staticMethod is the name of the static method.
For examples of function methods, see the built-in Function.call( ) and Function.apply( ) methods in the ActionScript Language Reference. These methods execute a function in the context of a specified object. We'll revisit static methods and the prototype property in Chapter 12.
Finally, because function objects are data, they can be returned by functions. The following example shows a function, makeGotoHandler( ), that returns a nested function literal for use as the callback of a movie clip event handler. The function literal sends the clip's playhead to the frame specified by frameNumber.
function makeGotoHandler (frameNumber) { return function ( ) { this.gotoAndStop(frameNumber); }; } // Usage: _root.onMouseDown = makeGotoHandler(30); _root.onMouseUp = makeGotoHandler(40);
Using makeGotoHandler( ), we can conveniently create a callback function without the work of actually typing out the function each time we want to assign it. Notice that we're once again using the scope chain to retrieve the value of frameNumber from the event handler callback, long after makeGotoHandler( ) has finished executing. For details, see Section 9.10.1, earlier in this chapter.