Function Closures, Local Functions, Generated Functions, Anonymous Functions… Yikes!

First of all, before we even start to address the topic of Function Closures, I should point out the pros and cons about them.

Pros:

– Short and Sweet;
– They look pretty;
– Good for simple tasks;
– Doesn’t require you to create a method on the Class;

Cons:

– Hard to keep track of execution;
– More difficult to debug;
– Known to be a popular cause for Memory Leaks (if not used correctly);
– The lack of ownership to one particular Class violates the best practices of OOP;

But nonetheless, here is an example for you courageous souls that wishes to harness the power of Function Closures:

package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	/**
	 * ...
	 * @author Pierre Chamberlain
	 */
	public class Main extends Sprite
	{
		
		public function Main() 
		{
			stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event=null):void 
		{
			e && removeEventListener(Event.ADDED_TO_STAGE, init);
			
			var dog:Animal =	new Animal("Dog", makeAction("Bark"));
			var bird:Animal =	new Animal("Bird", makeAction("Chirp"));
			var cow:Animal =	new Animal("Cow", makeAction("Moo"));
			
			dog.cry();
			bird.cry();
			cow.cry();
		}
		
		//Function-Closure factory method:
		private function makeAction(pNameOfSound:String):Function {
			var f:Function = function():void {
				/* 
				 * Cast 'this' as Animal since we know it will
				 * always be one, in this example.
				 */
				var theName:String =	Animal(this).name;
				var theSound:String =	pNameOfSound.toUpperCase();
				trace("The " + theName + " cries... '" + theSound + "'!!!'");
			};
			
			return f;
		}
	}
}


internal class Animal {
	private var _name:String;
	private var _cryFunc:Function;
	
	public function Animal(pName:String, pCryFunction:Function) {
		_name = 	pName;
		_cryFunc =	pCryFunction;
	}
	
	public function cry():void {
		/*
		 * The 'this' keyword is necessary so that the function knows that
		 * this instance of animal is the scope of the function-closure.
		 */
		_cryFunc.apply(this);
	}
	
	public function get name():String 
	{
		return _name;
	}
}