Nested Functions and Function Variables
Turns out that AS3 supports ! I have been making Function variables for a long time. Read on for the greatness that is nested functions.
To prove that I just found out about this, see this previous article where I made a local variable of type Function. Here is the old way of doing it:
function foo(): void { var goo:Function = function(): void { trace("goo"); }; trace("begin foo"); goo(); trace("end foo"); }
This works and prints:
begin foo goo end foo
Now behold the glorious new way with nested functions:
function foo(): void { function goo(): void { trace("goo"); } trace("begin foo"); goo(); trace("end foo"); }
Indeed, this prints the same thing. This is much cleaner, at least to my eyes. You get to use the same syntax that you use for all your other functions. There is, however, a downside. Just like with the other functions you define, you can’t have two with the same name. Consider this:
function foo(): void { trace("first foo"); } foo(); function foo(): void { trace("second foo"); } foo();
This gives a compiler error:
Error: Duplicate function definition.
With Function variables though, you’re free to get around this:
var foo:Function = function(): void { trace("first foo"); }; foo(); foo = function(): void { trace("second foo"); }; foo();
And you will get the anticipated result:
first foo second foo
But there is a workaround that rather cleanly gets you the best of both worlds:
function foo(): void { trace("first foo"); } foo(); // Simply re-assign foo here: foo = function foo(): void { trace("second foo"); } foo();
It’s not common that you’d want to do this, but it can come up in some special circumstances. You can use both nested functions and function variables together to get an even more powerful combination:
function example(): void { function foo(): void { } function goo(): void { } // The current function is always curFunc var curFunc:Function = foo; // ... code with: curFunc() curFunc = goo; // ... code with curFunc() curFunc = foo; // ... code with curFunc() }
This allows you to switch the function doing some processing without cluttering up using an if statement. Be careful though- these function calls are dynamic and will be quite slow. So use this sparingly.