BIT-101 [2003-2017]

Scope in AS2 Classes revisited, again.


A while back I did a post or two on handling scope issues in AS2 classes. (This is still something that constantly comes up on Flashcoders, etc.)

To recap, say you have a class, and you create an XML object and load in some XML. you set the onLoad handler of the XML object so that you know when it’s done loading (or not).

class MyClass {
     function getXML(){
          var myXML:XML = new XML();
          myXML.onLoad = function(){
               trace(this);
          }
          myXML.load("some.xml");
     }
}

OK, good enough. But once you’ve loaded and parsed the xml, you probably want to use it somehow in your class. But, from within the xml onLoad handler, there is no reference back to the class! _parent doesn’t work, as that’s a MovieClip property. You could try giving the xml object a property like “owner”, and referencing it in the onLoad handler as this.owner, but the XML object is not dynamic, so you can’t just add properties to it like that.

I wound up going in and creating a new class that extended XML, and added some facilities for it to contact its enclosing class. Others did the same. At the time, this felt like a nice, solid OOP-based solution.

In the many months following that, though, I found that although I ran into this situation almost daily, I rarely, if ever, used that solution. Generally what I wind up doing is creating a local variable just before creating the XML object, and assinging “this” to it. The onLoad handler has access to local variables in the scope where it’s defined. I then use that local var to access the class.

Of course, this method was known at the time, and even mentioned by myself as a possible solution, but I really didn’t like the idea of defining an event handling function within a method of a class. I don’t think nested functions are a really good practice.

In regular practice though, I have comprimised a bit on that viewpoint. I allow myself one line, which calls a class method on the local var reference to the class, passing in the xml data. Looks like this:

class MyClass {
     function getXML(){
          var app = this;
          var myXML:XML = new XML();
          myXML.onLoad = function(){
               app.parseXML(this.firstChild);
          }
          myXML.load("some.xml");
     }
     private function parseXML(someXML:XMLNode){
          // do stuff with someXML
          // the scope is now back to the class itself,
          // and I have all my xml data right here.
     }
}

I’ve found this to be the most pragmatic approach. Same thing applies for onPresses, onStatuses, onChangeds, etc. Of course, if you are using an object that supports _parent, you can skip the whole local variable thing.

« Previous Post
Next Post »