views:

85

answers:

2
A.as : 

    public class A {

    public function getFunction():Function { 
      return function():void {
        if(this is C) {
          trace("C");
        } else {
          trace("not C");
        }
     }
  }


public function func1():void {
   var internalFunc:Function = getFunction();
   internalFunc();
 }

}

B.as : 
public class B extends A implements C {

}

In some other class :

var b:B = new B();
   B.func1();

Output is : "Not C"

I was expecting the trace output to be
"C"

Can someone explain why?

+4  A: 

An anonymous function, if called directly, is scoped to the global object. If you trace this inside it, you will see [object global] instead of [object B], as you would, if this refered to b.

A common workaround is using a closure:

  var self:A = this;
  return function():void {
    if(self is C) {
      trace("C");
    } else {
      trace("not C");
    }
 }

Please note however, the instance-members of a class defining an anonymous function are available from within. This works, because they are resolved at compile time.

edit in response to Amarghosh's question:

Yes, this points to the global object, but that doesn't mean, you cannot access the instance members of the declaring class. This little piece of code should explain the details:

package  {
 import flash.display.Sprite;
 public class Test extends Sprite {
  private var foo:String = "foo";
  public function Test() {
   var anonymous:Function = function ():void {
    trace(foo);//foo
    trace(this.foo);//undefined
   };
   anonymous();
  } 
 }
}

greetz
back2dos

back2dos
His code sample doesn't have an anonymous function, though. Here is a good write up on anonymous functions in Flex: http://www.darronschall.com/weblog/2004/08/anonymous-inline-and-named-functions-in-actionscript.cfm
www.Flextras.com
instance members will be available only if you assign `this` to a local variable within the enclosing function, right? Otherwise with `this` pointing to global, what would you use to refer to them?
Amarghosh
@www.Flextras.com : See Amarghosh's comment to your response.
back2dos
@Amarghosh: I updated my answer to explain. ;)
back2dos
@back2dos I saw it; I must have done a bad copy and paste job when I tried to run his code.
www.Flextras.com
+1  A: 

A few things with the code that I assume are just typos?

The getFunction() method doesn't return anything and will thus cause a compiler error.
Your call code calls func1() as a static method, not as a method on an instance of the B. This will also cause a compiler error. I believe these are typos.

In my tests, using your modified code. The output is C. There must be something else going on with your code. Here are my mods to A:

    public function getFunction():Function { 
        if(this is C) {
            trace("C");
        } else {
            trace("not C");
        }
        return getFunction;
    }

Here is my mod to the runnable code, which I put in creationComplete of an empty MXML Application file:

            var b:B = new B();
            b.func1();

I assume your "real world" code is more extensive than the sample and there must be something else going on.

www.Flextras.com
He is returning an anonymous function from `getFunction` and calling it from `func1` - `this` will be `global` as suggested by back2dos
Amarghosh
I must have copied and pasted his code incorrectly when I tried to run it; as the getFunction was returning nothing.
www.Flextras.com
@flextras.com, you did not copy it incorrectly :-). I had edited my code after posting it for the first time..
dta
@dta, Thanks for the clarification; good to know I'm that crazy yet. :-)
www.Flextras.com