Tips: Using the Delegate class to manage scope

Basically, whenever you are passing around a Function object in Actionscript, that object is decoupled from whatever class it was written for. What this means that if that function has references to “this”, these references will refer to whichever object that will be the execution scope of the function when the function will execute.

For example, suppose you are creating a Mouse Listener :

var mListener:Object=new Object();
     mListener.onMouseDown=function():Void{
         trace(this) // [Object Object]
    }
    Mouse.addListener(mListener);

Here, “this” is a reference to the mouseListener
but if you use the mx.utils.Delegate class :

import mx.utils.Delegate;
var mListener:Object=new Object();
     mListener.onMouseDown=Delegate.create(this,mousePressDown);
     function mousePressDown():Void{
        trace(this) // _level0
    }
    Mouse.addListener(mListener);

Here, “this” is a reference to the context of the mouse listener.

The Delegate class is used to specify this context(or scope). In the flash documentation you can read : “The Delegate class creates a function wrapper to let you run a function in the context of the original object, rather than in the context of the second object, when you pass a function from one object to another.”

If you open the class you will see (luckily, this class is only a few line long) :

class mx.utils.Delegate extends Object
{
	/**
	Creates a functions wrapper for the original function so that it runs 
	in the provided context.
	@parameter obj Context in which to run the function.
	@paramater func Function to run.
	*/
	static function create(obj:Object, func:Function):Function
	{
		var f = function()
		{
			var target = arguments.callee.target;
			var func = arguments.callee.func;
 
			return func.apply(target, arguments);
		};
 
		f.target = obj;
		f.func = func;
 
		return f;
	}
 
	function Delegate(f:Function)
	{
		func = f;
	}
 
	private var func:Function;
 
	function createDelegate(obj:Object):Function
	{
		return create(obj, func);
	}
}

In ActionScript, each function has a method “apply” which takes two arguments apply(scope, arguments), the scope of the function, and all arguments given to the function when the function is called.

The create() method of the class Delegate, takes two arguments, the scope in which the function will be executed and the function to execute and returns a reference to another function, which is a “wrapper” of the original.
When the delegate is called, it simply executes the original function in the desired scope with the help of the apply method !
It’s a static method, you did not need to create an instance of the Delegate object in order for it to work. You can simply call it directly as mx.utils.Delegate.create() which returned you the new “delegated” function.


About this entry