Functions as Objects - Part 1

For many people who learned how to program line by line, better known as procedurally, and then learned Object-Oriented Programming later, thinking of functions as Objects may not come naturally. Learning functions as objects can be very powerful and, though it doesn't solve every problem ( what does? ), they definately make many problems much easier to solve. In part 1 of Functions as objects I discuss the basics of using Function objects with many examples for each point. ... Because I currently do most of my programming in Actionscript 2.0, the examples in this article will be in that format. However, information should still easily be gleaned from my examples for other languages.

To start thinking about functions as objects, Function objects ( note the capital 'F' ), we will start with the basics of what makes an object. Objects have properties and methods, and Function objects are no different. Function objects, in Actionscript, have one property called 'arguments'. Put simply, 'arguments' is an object that holds the arguments that are passed into a function when it is called. We will talk about the functionality and use of 'arguments' in the part 2 of this article. As for methods, Function objects in actionscript have 2, 'call' and 'apply'. The methods 'call' and 'apply' are very similar and will be discussed more in part 2. To give you a basic idea, they give you some alternative ways to call a function.

Now that we know functions act like an object and look like an object, lets take a look at how to use them as objects. When you have another object, say an Array object you can store it ( or rather its memory location ) in a variable. First, you need a variable that can hold your object. For an Array:

var myArray:Array;

For a Function:

var myFunc:Function;

Now that we have our variables let's point them to our objects. You could point 'myArray' to a new Array object that you create with the 'new' operator. For example:

myArray = new Array()

For Function objects you don't use the 'new' operator, but rather pass a function literal like this:

myFunc = function( ){ return "Hello World" }

You can also point variables to objects, Function or otherwise, that are already in existense by pointing to other variables of the same type. For example:

var myMC:MovieClip = _root

and for a Function object:

var myFunc:Function = _root.onEnterFrame

Finally let's compare the two ways to declare and initialize a variable that points to a Function object:

var myFunc:Function = function( ){ return "Hello World"; }

can be written as:

function myFunc( ){
  return "Hello World";
}

The second way is probably more familiar but they are identical. Either ways you write declare and initialize 'myFunc' you can still call it by doing this:

myFunc()

And still point it to another function like this:

myFunc = function( name:String ):String{
  return "Hello " + name;
}

In my last example I typed the return of myFunc. In simpler English, I said that when I call the function it will return a certain data type ( in this case a String ). This is important for understanding the difference between 'myFunc' and 'myFunc()'. 'myFunc' is a variable that points to a Function object and myFunc() is a call to function that 'myFunc' points to and since I typed that function's return I know it will be a String. The best example is this:

function myFunc( ):String
{
  return "Hello World";
}

trace( "myFunc = " + myFunc ); // outputs myFunc = [Function object]

trace( "myFunc() = " + myFunc() ); // outputs myFunc() = Hello World

Let's make it a little more advanced by using a calling myFunc as different functions:

var myFunc:Function = function()
{
  trace( "Hello World" );
}

var myOtherFunc:Function = myFunc;

myFunc(); // output: Hello World
myOtherFunc(); // output: Hello World

myFunc = function( a, b )
{
  trace( a + " + " + b + " = " + ( a + b ) );
}

myFunc( 2, 3 ); // output: 2 + 3 = 5
myOtherFunc( 2, 3 ); // output: Hello World

In the last example myFunc gets initialized with a function literal and myOtherFunc was initialized by pointing to myFunc. So it is no suprise when they both output the same thing. However, myFunc then points to a new function and outputs what you would expect. myOtherFunc, on the other hand, still outputs 'Hello World'. This happens because it still points to the original Function object.

Hopefully this article gave some insight into using functions as objects. Be watching for part 2 of this article when I discuss scope, FunctionArguments and using functions in other functions.