Wordsligner • Dissident • Webwright

Scope in ActionScript 3 is so fubared I can barely express it in words

Published 19 October 2008

This looks wrong:

package {
  public class ScopeFu {

    private static var var0:String = 'var 0';
    public static var var1:String  = 'var 1';

    private var var2:string = 'var 2';
    public var var3:String = 'var 3';

    public function ScopeFu(var4:String = 'var 4') {
      var var5  = 'var 5';

      trace(var0);
      trace(var1);
      trace(var2);
      trace(var3);
      trace(var4);
      trace(var5);
    }
  }
}

And yet it works.

Compared to JavaScript:

var ScopeFu;
(function() {
  var var0 = 'var 0';

  ScopeFu = function(var4) {
    this.var2  = 'var 2';
    this.var3  = 'var3';
    var4       = var4 || 'var 4';
    var var5   = 'var 5';

    console.log(var0);
    console.log(ScopeFu.var1);
    console.log(this.var2);
    console.log(this.var3);
    console.log(var4);
    console.log(var5);
  }
  ScopeFu.var1 = 'var 1';
})();

Still a mess. The JavaScript syntax is a little more cryptic and var2 isn’t private, yet there are half as many scope collisions. The ones that do exist are only because JavaScript doesn’t really support private members; I’m using closures to fake it.

In either case, scope can become a nightmare in large applications when you’re trying to figure out where something is defined, especially when you’re jumping back and forth between the otherwise-similar languages. Underscores and access methods can help, so long as you are disciplined enough to be consistent:

Preferred prefixes and access methods for variable scope in ActionScript and JavaScript
Scope Prefix Access Example
Private Static Three Underscores local ___var0
Public Static none via class ScopeFu.var1
Private Instance Two Underscores this (JavaScript only) this.__var2 or __var2
Public Instance none this this.var3
Function Argument One Underscore local _var4
Function Member none local var5

Adopting these kinds of conventions may help keep scope sorted amongst a group of developers.