tutorials flex protect_scope

Protection for method scope of a class in AS3.

Article written the 07/04/2008 00:25.
By ekameleon ( ekameleon ).

The problem

While working on more experiments in Actionscript 3 I have just realised (even if the information is not new) that there is a major difference regarding the scope of class methods between AS2/AS1 and AS3 (the target reference which returns the object ‘this’ in a function).

The workings of method scope and functions in AS2

I will start by illustrating scope methods and the function of a class with an example in AS2:

class TestMethodScope
{
 
	/**
	 * Creates a new TestMethodScope instance (constructor)
	 */
	public function TestMethodScope()
	{
 
		//// TEST 1
 
		var o:Object = {} ;
		o.toString = function():String
		{
			return "[test Object]" ;
		}
 
		var test1:Function = function():Void
		{	
			trace( "test 1 : " + this + " " + arguments) ;	
		}
 
		// default scope
 
		test1("arg1", "arg2") ;
 
		// test scope
 
		test1.apply( o , ["arg1", "arg2"] ) ;
 
		//// TEST 2
 
		// default scope
 
		test2("arg1", "arg2") ;
 
		// test scope
 
		test2.apply( o , ["arg1", "arg2"] ) ;
	}
 
	public function test2():Void
	{
		trace( "test 2 : " + this + " " + arguments) ;	
	}
 
	/**
	 * Returns the String representation of the object.
	 * @return the String representation of the object.
	 */
	public function toString():String
	{
		return "[TestMethodScope]" ;
	}
 
	/**
	 * Launch the application.
	 */
	public static function main( target:MovieClip ):Void
	{
		var app:TestMethodScope = new TestMethodScope() ;
	}
 
 
}

To launch this example you need to put the following code into a Flash document with the publication parameters defined in AS2:

TestMethodScope.main(this) ;

Here is the result in Flash’s output panel for this example:

test 1 : undefined arg1,arg2
test 1 : [test Object] arg1,arg2
test 2 : [TestMethodScope] arg1,arg2
test 2 : [test Object] arg1,arg2

Let’s look at the code in more detail.

The example above can be separated into 4 parts:

To test the scope of a local function called in the constructor or a class method.

In our first case the scope is undefined (see output “test 1 : undefined arg1,arg2”).

The local function therefore belongs to no particular object in AS2.

To test the scope of a local function called via the method ‘apply’ with modification of the scope using the first parameter of the method ‘apply’.

We modify the scope of the function with the apply method. The function now has a reference with the keyword ‘this’.

To test the scope of a method of the directly called upon class.

Here is the traditional use of a class method, the scope in this case is quite simply the instance of the class which is using the method.

To test the scope of a class method called via the method ‘apply’ with modification of the scope using the first parameter of the method ‘apply’.

The method is called upon as in the preceding case but the scope of the method has changed. The apply method apply encounters no problems in AS2 (we will see that in AS3 we do not get the same result).

The workings of method scope and functions in AS3

Let us take the preceding AS2 example and let’s quickly adapt it in AS3 in Flex or Flash CS3. For this example I have created a small AS3 class TestMethodScope which will be our “main” class for this test application:

package
{
	import flash.display.Sprite;
 
	public class TestMethodScope extends Sprite
	{
 
		public function TestMethodScope()
		{
 
			//// TEST 1
 
			var o:Object = {} ;
			o.toString = function():String
			{
				return "[test Object]" ;
			}
 
			var test1:Function = function( ...args:Array ) :void
			{	
				trace( "test 1 : " + this + " " + args) ;	
			}
 
			// default scope
 
			test1("arg1", "arg2") ;
 
			// test scope
 
			test1.apply( o , ["arg1", "arg2"] ) ;
 
			//// TEST 2
 
			// default scope
 
			test2("arg1", "arg2") ;
 
			// test scope
 
			test2.apply( o , ["arg1", "arg2"] ) ;
		}
 
		public function test2( ...args:Array ):void
		{
			trace( "test 2 : " + this + " " + args) ;	
		}
 
	}
 
}

The example is practically the same as in AS2 but now let’s see the result in the output window of Flex after launching the application:

test 1 : [object global] arg1,arg2
test 1 : [test Object] arg1,arg2
test 2 : [object TestMethodScope] arg1,arg2
test 2 : [object TestMethodScope] arg1,arg2

Here are our 4 test situations again but we can see differences for each stage.

To test the scope of a local function called in the constructor or a class method.

In AS3 the scope of a local function is not undefined any more but targets the global reference of the AS3 application ([object global]).

To test the scope of a local function called via the method ‘apply’ with modification of the scope using the first parameter of the method ‘apply’.

No difference, as in AS1 or AS2 we modify the scope function with the apply method. The function now has a reference towards the generic object defined in the constructor of the class with the keyword ‘this’.

To test the scope of a method of the directly called class.

No difference either at this stage. As in AS2 we are in the traditional use of a class method, the scope in this case is quite simply the instance of the class which is using the method.

To test the scope of a class method called via the method ‘apply’ with modification of the scope using the first parameter of the method ‘apply’.

The method is called upon as in the preceding case but the scope of the method has not changed. The method apply encounters a problem in AS3, it would seem that the methods of a class cannot correctly use their methods ‘call’ and ‘apply’. No modification of the function scope is possible.

Conclusion

I think that there must be a reason that Adobe have put in place such a protection on method scope of classes in AS3. All that now remains is to know why? I have not found much on the subject on Google and I have not yet found more on the subject in the specifications of AS3 language or in ECMAScript 4 (but maybe I did not look carefully enough).

I will continue my research on the subject while hoping to find out more because at the moment I am a bit stuck. When we are used to using the Delegate class for example in AS1 or AS2… it can be somewhat unnerving in AS3 not to be able to create a proxy on the class method as we did in AS1/2.

If you have any more information on the subject I would love to know it.

More information








Adobe Training center


Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42