Search code examples
actionscript-3actionscriptcall

What is wrong in my example of using the 'call' method in Actionscript 3?


I'm trying to learn OOP on my own using AS3, and I've given myself a challenge for that purpose. Because it's quite a complex one, I'm trying to understand useful tools in AS3.

At any rate, the function.call (AS3 API's doc. here) method looks quite interesting, and I think I would be able to put that into use, however I apparently don't understand fully what it does and how it works. JavaScript seems to have an equivalent that looks pretty straightforward to use. (I saw this other thread with the same question as mine, but in JS)

Here's an example of what I thought the function.call would do.

package
{
    import flash.display.Sprite

    public class Main extends Sprite 
    {

        public var foo:Foo;
        public var bar:Bar;

        public function Main() 
        {
            foo = new Foo();
            bar = new Bar();

            trace(bar.barProperty); //Hello World!

            //I expect the 'foo.BarProp' to be called with this==bar.
            foo.value = foo.BarProp.call(bar); //ReferenceError: Error #1069: Property barProperty not found on Main.as$0.Foo and there is no default value.

            trace(foo.value); //Expected output: Hello World!
        }

    }

}

class Foo {

    public var value:String;

    public function Foo() {}

    public function BarProp():String {
        return this.barProperty;
    }
}

class Bar {

    public var barProperty:String = "Hello World!";

    public function Bar() {}
}

All right, so what is it that I'm just not getting?


Solution

  • First of all, return this.barProperty should be giving you compile errors, since there is no barProperty on this where you've written that code.

    Second of all, I don't think Function/call() can change the meaning of this for class instance methods. It works for object functions:

    var foo:Object = {
        getBarProperty: function(){
            return this.barProperty;
        }
    }
    
    var bar:Object = { // or use your Bar class
        barProperty: "Hello World"
    }
    
    trace(foo.getBarProperty.call(bar)); // "Hello World"
    
    foo.getBarProperty(); // "undefined", because "foo" does not have a "barProperty"
    

    This is the same as Javascript, but Javascript does not have classes and instance functions, and this is infamously not always lexical, so using call() and apply() with a thisArg is more common practice. In about 10 years of ActionScript 3 development I cannot remember once needing to use call() with a different thisArgument.