Table of Contents

Function.apply( ) Method Flash 6

invoke a function as an object method, passing parameters in an array
theFunction.apply(thisObj, parametersArray)

Arguments

thisObj

The object on which theFunction is called as a method.

parametersArray

An array of values passed as arguments to theFunction.

Returns

The return value of theFunction.

Description

The apply( ) method invokes theFunction as a method of thisObj and passes the values of parametersArray to theFunction as arguments. Within theFunction, the value of the this keyword is a reference to thisObj. The return value of apply( ) is simply the return value of theFunction. To invoke theFunction without specifying an object reference, use null as the value of thisObj. To pass a comma-delimited list of arguments to theFunction, instead of passing the values in a parametersArray, use Function.call( ).

The apply( ) method is normally used to alter the value of the this keyword when running a function, or to supply an array of arguments to a function in place of a comma-delimited list.

The following code shows the basic syntax of apply( ):

// Create a function
function square (x) {
  return x*x;
}
   
// Invoke the function as a method of _root, passing an array literal
// containing the single argument value 10.
tenSquared = square.apply(_root, [10]);

This example has little practical purpose�it would be easier to invoke the function directly, as in: _root.square(10);. The apply( ) method becomes more useful when we need to dynamically specify the object on which to invoke a method, for example, when we want to use one method with many different objects that do not share a common class or superclass. Suppose we have getWidth( ) and moveClipTo( ) methods that we want to use with both a rectangle and a circle object. Here's the code we can use to create a generic method, Rectangle.invokeAsMethod( ), that invokes getWidth( ), moveClipTo( ), or any other function as a method of a rectangle object:

// A Rect class
function Rect (width, height, x, y) {
  this.width = width;
  this.height = height;
  this.x = x;
  this.y = y;
}
   
// Method to invoke any passed func as a method of a Rect object.
// Note that func is a function reference, not a string.
Rect.prototype.invokeAsMethod = function (func) {
  // Invoke func as a method of this Rect, passing along any
  // arguments that were supplied.
  func.apply(this, arguments.slice(1));
};
   
// A simple generic getWidth function that takes no arguments
function getWidth () {
  trace("width: " + this.width);
  return this.width;
}
   
// A slightly more complex example, moveClipTo, that takes arguments
function moveClipTo (newX, newY) {
  this.x = newX;
  this.y = newY;
}
   
// Make a new Rect object
box = new Rect(15, 20);
// Invoke getWidth on box
box.invokeAsMethod(getWidth);  // Displays: width: 15
// Invoke moveClipTo on box, passing the newX and newY arguments
box.invokeAsMethod(moveClipTo, 100, 200);
// Check if it worked...
trace("box x: " + box.x);  // Displays: box x: 100
trace("box y: " + box.y);  // Displays: box y: 200

This practice is not necessarily recommended when the objects can logically be assigned a common class or superclass. For example, rather than use apply( ) in our rectangle example, it's more appropriate to create a Shape superclass that defines moveClipTo( ) and getWidth( ) methods inherited by both Rect and Circle. For a more legitimate application of the apply( ) method, see the CountDown class shown in the following Example.

Example

The following class, CountDown, invokes a specified object's method after a delay. It uses apply( ) to ensure that the method executes on the correct object and to pass the method arguments as a convenient array.

/*
 * CountDown Class
 *   Desc: Calls a method after delay milliseconds.
 * Params: obj  An object whose method will be called.
 *        meth  The string method name to call.
 *       delay  The time (milliseconds) to wait before calling.
 * arg4...argn  The arguments to pass to meth.
 */
function CountDown (obj, meth, delay) {
  // Remember how long to wait before calling meth.
  this.delay = delay;
  // Store a reference to the method.
  this.callback = obj[meth];
  // Store a reference to the object.
  this.obj = obj;
  // Store extra arguments. We'll pass them to meth later.
  this.args = arguments.slice(3);
  // Set an empty intervalID. Used with setInterval().
  this.intervalID = -1;
  // Start the countdown
  this.start();
}
   
/*
 * Method: start()
 */
CountDown.prototype.start = function () {
  // Invoke the method-caller after this.delay milliseconds.
  this.intervalID = setInterval(this, "invokeCallback", this.delay);
};
   
/*
 * Method: stop()
 */
CountDown.prototype.stop = function () {
  // Stop the interval so that it doesn't call the method again.
  clearInterval(this.intervalID);
  this.intervalID = -1;
};
   
/*
 * Method: invokeCallback()
 */
CountDown.prototype.invokeCallback = function () {
  // Time's up! Stop the countdown.
  this.stop();
  // Invoke the callback as a method of this.obj, and pass
  // along this.args to use as method arguments.
  this.callback.apply(this.obj, this.args);
};
   
// SAMPLE USE
// Create the countdown. Will invoke
// _root.output("hello", "world") after 1000 milliseconds.
count = new CountDown(_root, "output", 1000, "hello", "world");
   
// The method to invoke
function output (arg1, arg2) {
  trace("output: " + arg1 + ", " + arg2);
}

See Also

Function.call( ), the Arguments object; Chapter 12


Table of Contents