Bill Kotsias
Bill Kotsias

Reputation: 3368

AS3 : What is the context of 'this' in an anonymous function?

In this example:

    public function Roulette() {
        new QuickLoad(url, function (o:*):void {trace(this);});
    }

when QuickLoad instance does its stuff, it calls the anonymous function. One would think that this is Roulette. But no, it turns out to be the anonymous function's caller, which is QuickLoad.

This is weird to say the least, say how am I supposed to pass the "correct" this (i.e. Roulette instance) inside the anonymous function if I don't do it the normal way?

Upvotes: 1

Views: 186

Answers (3)

Vesper
Vesper

Reputation: 18747

There is a way to call a function with an alternate this pointer, but since your function is called from within new QuickLoad(), you need to alter that call statement, and pass your this as Roulette into the constructor. Your new QuickLoad object is unaware of its surroundings, and even the caller of the constructor is unknown to it. Thus, you need to make it aware, pass a this pointer from Roulette() to QuickLoad(), AND call the function from QuickLoad with passing an alternate this pointer.

public function QuickLoad(url:String,caller:Object=null,callback:Function=null) {
    // initialization code
    if (callback!=null) {
        if (caller!=null) callback.apply(caller,[o]);
        else callback.apply(this,[o]);
    }
}
...
public function Roulette() {
    new QuickLoad(url, this, function (o:*):void {trace(this);});
}

Function::apply() manual.

You can also use call() method, if your argument array has fixed length. callback.call(caller,o);

Upvotes: 2

CodeMouse92
CodeMouse92

Reputation: 6898

Generally, in this context, this refers to an object. To quote a rather infamous acronym: INABIAF (It's not a bug, it's a feature), LOL. So, yes, the object instance QuickLoad that is calling the function is going to be what this looks at by default.

There is an exception I know of (out of many, I'm sure)...you can get anything...variable, function, object, whatever, via this["Name of Object"]. But that's an aside.

There ARE other workarounds, I'm sure, which may or may not be practical for your purposes. This is one way of passing a function, out of many, and it's the one I use the most.

Functions do not have instances. They're not objects. If you want to send a function as an argument to another function, you simply pass it, as follows in this rather weird example.

//This function accepts a function as an argument.
function bridgeOfQuestions(person:String, response:Function):void
{
    if(person == "King Arthur")
    {
        response("What is the average airspeed velocity of an unladen swallow?");
    }
    else
    {
        response("What is your favorite color?");
    }
}

//This is the function we're going to pass.
function askQuestion(question:String):void
{
    trace(question);
}

//Here, we call bridgeOfQuestions and pass it the askQuestion function.
//NOTE: Leave off the parenthesis on the function being passed!
bridgeOfQuestions("Sir Lancelot", askQuestion);
bridgeOfQuestions("King Arthur", askQuestion);

EDIT: If it is just the name you're passing, a function is a function permanently. It doesn't change, unlike an object, and as I said, it doesn't have instances. Therefore, if you merely want to print out the name of the function, you'd only use trace("Roulette").

Upvotes: 1

Alexis King
Alexis King

Reputation: 43852

Just save the outer this instance under a different name so that it is preserved:

public function Roulette() {
    var rouletteThis = this;
    new QuickLoad(url, function (o:*):void {trace(rouletteThis);});
}

Upvotes: 2

Related Questions