Global Variables in AS3 ·
16 August 2007, 10:50

EDIT — 09/03/09 I decided to update this article in response to some of the comments about the potential dangers of using global properties. Its a convenient way to store variables that are accessible from anywhere in your project, but with great power comes great responsibility :).

Yes, we know it can get sloppy, but sometimes is just makes sense to create variables that are accessible from anywhere in your project.

Prior to AS3 it was really easy… there was the _global object: _globals.myvar = 'mystring'. You are most likely reading this because you are trying to use the _global object in AS3. Ecmascript (the standard on which AS3 is based) does not support this notion, rather it forces you to create your own globally accessible object if you so desire. They are encouraging instance based data coupling, because it’s a lot more structured and less error prone. If you are working on a large application, I will encourage you to not use global variables (especially if unit testing is a requirement). However, if you don’t give a damn about what us programming snobs say, have no idea what unit testing is, or just want to use some global variables in AS3, then don’t feel bad, they can be quite handy!

So how do we create variables in AS3 that are globally accessible from anywhere a project? Well, its as easy as building a class with a static variable container. Let’s use an Object as our variable container as they are dynamic meaning we can add properties (our variables of any type) at runtime. Here is the class:

package com.greenethumb.utils 
{
    public class GlobalVarContainer 
    {
        public static var vars:Object = {};
    }
}

To use this global variable container, just import GlobalVarContainer into whatever class you would like to read/write/create your global variables. Here is a sample:

package 
{
    import flash.display.Sprite;
    import com.greenethumb.utils.globalvars.GlobalVarContainer;
    public class Main extends Sprite
    {   
        public function Main()
        {   
            GlobalVarContainer.vars.groupingID  = 1 
            GlobalVarContainer.vars.mediaID     = 4 
            GlobalVarContainer.vars.facultyID   = 5 
            GlobalVarContainer.vars.studentID   = 2 
        }
    }
}

Werd up… globally accessible vars in AS3


Jonathan Greene

comments:

  1. thanks, I’m confused by this problem.

    this post is great help to me.

    syler · Nov 15, 02:38 AM · #

  2. but how do you do access the global variable from inside the fla file.

    atishay · Dec 3, 05:31 AM · #

  3. hey atishay,

    the _globals object no longer exists in AS3. It is not a part of the Actionscript Virtual Machine 2 (Flash player 9’s AS3 runtime). You can use this static GlobalVarContainer class to replicate the functionality of the _globals object. If you need to reference the GlobalVarContainer in your FLA, you do it the same way as you would access it from a class in a package: import the GlobalVarContainer class and read and write properties to its vars property. Hope that clears things up.

    Jon · Dec 4, 12:57 AM · #

  4. Thanks Jon, this was really helpful!

    Johan Nyberg · Dec 10, 08:58 AM · #

  5. One question – where is the document class instanciated? Is there a way for other objects in the fla to access public properties of the document class?

    Can’t seem to find your email on the site, so it you care to drop me a line I’d be really grateful. :-)

    Johan Nyberg · Dec 10, 09:15 AM · #

  6. Hey Johan, the Document Class is instantiated when your SWF is initialized. The Flash Player will automatically call the constructor function of your Document Class when your SWF initializes. If you do not specify a Document Class for your project, the compiler will automatically create a MovieClip instance an assign it as your project’s document class.

    It is possible to reference members of the your Document class from other elements in your FLA. For more details on that have a look at http://greenethumb.com/article/23/understanding-root-and-the-document-class-in-as3.

    Jon · Dec 11, 01:03 PM · #

  7. hey, just a heads-up re AS3’s ‘static’ keyword. i’m not sure whether this is a bug or a deliberate design decision, but the ‘static’ness of a variable does not propagate up the document tree to the root.

    let me give an example. suppose you have a document class MyDocumentClass that loads as two children movie_a.swf and movie_b.swf. suppose also you have class MultiLangManager, with a static function GetInstance() that fetches the static singleton instance, constructing a new one if necessary. like this:

    class MultiLangManager() { private static var instance:MultiLangManager = null; public static function GetInstance() : MultiLangManager() { if ( ! instance ) { trace(“constructing singleton instance”); instance = new MultiLangManager(); } return instance; } }

    (ps your blog commenting system’s ‘@’ code modifier is @broken@)

    now, at some point movie_a.swf calls MultiLangManager.GetInstance(). MultiLangManager goes ahead and constructs the singleton. sometime later, movie_b.swf calls MultiLangManager.GetInstance(). you’d expect MultiLangManager to return the existing instance. it is static, after all, right? wrong. what you get is another singleton, that is also static, but only ‘locally’ static. you know this, because the console says “constructing singleton instance” not once, but twice.

    thanks Adobe. you suck. when on earth this could be useful, i have absolutely no idea.

    the way around this is, if you add to the MyDocumentClass constructer, the line
    MultiLangManager.GetInstance()
    it will construct a properly singleton properly static instance that is then visible by both movie_a.swf and movie_b.swf.

    which means, of course, that MyDocumentClass has to know which static things both movie_a.swf and movie_b.swf are going to access. considering the fact that ‘static’ is supposed to be an elegant work-around to the problem of sharing data between instances without requiring some tight coupling in the middle, Adobe’s implementation is somewhat broken, to say the least, since it brings the coupling issue right back to the foreground.

    damian stewart · Jul 31, 07:42 AM · #

  8. Meh, so much work for global variables.
    Why the heck couldn’t they add a global var myvar=1;
    to make things simple.
    >_< I hate Adobe.

    ex · Aug 26, 06:43 AM · #

  9. Anyone who needs a cross project (multi SWF file) please read carefully the comment above me by damian Stewartws. Only his fix makes it work cross-SWF.

    Barak Siman Ov · Sep 4, 08:00 PM · #

  10. thanks for the tips guys. i have not run into this prob yet… could it be when you are loading in your child swfs they are not given access to the DocumentClass’s application domain? Not sure… just wondering…

    and yeah, posting code in comments on this blog is pretty broken :)

    Jonathan Greene · Sep 4, 09:14 PM · #

  11. Im confused… So how is this set up in th FLA?

    I put the as code above with the GlobalVarContainer statements in an as file and import it yes? Then what in the fla?

    Jim Smitze · Sep 30, 11:00 PM · #

  12. Good tip, thanks!
    Let’s say I have 3 classes. Is it possible to have a public static boolean that can permeate through each class? I’m worried that by importing the var into another class and changing it’s value there it won’t reflect the change if used in another class. Or will it?

    Jonathan Dumaine · Oct 11, 11:28 PM · #

  13. Is there a way I can send a _global value from AS2 to AS3? The main movie is created using AS2 then we migrate to AS3 and I made a mistake of using AS3 in the child movie that needed to be called into the main movie (AS2). Now I have a problem sending the _global variable from the main movie that the child movie (AS3).

    Thomas Brown · Oct 23, 10:13 AM · #

  14. Thanks so much. I’ve been having problems with development ever since global vars were taken out.

    Nick · Nov 18, 06:48 PM · #

  15. Ref message 25, can you explain more? I tried the code below but get “1046: Type was not found or was not a compile-time constant: GlobalVarContainer.

    import com.greenethumb.utils.globalvars.GlobalVarContainer;
    var gvc:GlobalVarContainer = new GlobalVarContainer;
    gvc.vars.groupingID=1;

    John · Nov 19, 04:07 AM · #

  16. As to the comments regarding static properties in the use case of Singletons. If you load movies using the same context, your Singletons (and static properties) will function as you expect.

    Adobe has provided different contexts for each movie that is loaded externally. This, my guess anyway, is a security feature to help sandbox externally loaded SWF files. But it doesn’t explain why calling the Singleton once from the main movie before calling it in the loaded movie also fixes the problem. That unfortunately makes no sense at all to me.

    Eric Stewart · Nov 25, 01:13 AM · #

  17. eerr you can do it like this? why all that package and complex stuff?

    var strGlobal:String = “Global”;
    function scopeTest()
    {

    this is from the adobe site i think trace(strGlobal); // Global
    }
    scopeTest();
    trace(strGlobal); // Global

    this is from adobe site i think

    John · Jan 7, 11:41 AM · #

  18. Thanks! I was sick and tired of sending events around

    Atro · Feb 12, 08:19 AM · #

  19. Thankz a lot Jon. but I was wondering why static on declaration of variables.

    This is my first code before I seen this site:

    @package gv{@

    @ public class globalVars{@

    @ private var sessID:String;@

    @ public function setSessID(sessVar:String):void{@

    @ sessID = sessVar;@

    @ }@

    @ public function getSess(sessVar:String):void{@

    @ sessID = sessVar;@

    @ }@

    @ }@

    @}@

    I was wondering why I get “Could not assign to static class [somthing]…”. Are Strings or Objects are normally constructed as static? My apology I have a little background on OOP.

    Thankz a lot.

    paulcortez · Mar 16, 12:02 PM · #

  20. Hey Paul,

    When a property is declared with the ‘static’ attribute, it means that that property is accessible on the Class level, not the instance level. By declaring a static method or property, you can access it without constructing a new instance of the class. You have probably used the Math class before. When you call Math.random(), you are really calling the static method ‘random()’ on the Math class. If the random() method was not static you would have to do something like:

    var myMath:Math = new Math()
    var rand:Number = myMath.random();

    instead the:

    var rand:Number = Math.random() is a nice shortcut.

    Static methods and properties are used a lot in Utility classes.. or classes that just store or process information.

    In your example above, you would have to create a new instance of the your class and write your sessId variable to that instance. You could run into problems, because you could have more than one instance of your global vars object, meaning more than one sessId.

    Although it might be getting out of the scope of this thread, a Singleton Pattern might be of some use to you, although this GlobalVars example will only allow for a single instance of itself :)

    btw, sorry for my comment code tags being busted… ill fix that eventually

    Jonathan · Mar 16, 07:21 PM · #

  21. How do you access the global variables set from other classes within the project?

    matt Booth · Mar 22, 02:27 AM · #

  22. this article just saved my sanity. Thanks boss!

    empirecola · Jul 16, 05:57 PM · #

  23. fantastic! seems I’ve been coming to your site more and more lately… hmmm

    Thanks!

    Scott · Jul 17, 01:33 PM · #

  24. awesome stuff! This is quite useful :D

    Michael Awesome · Jul 19, 08:01 PM · #

  25. Perfect! Thanks :)

    Joe · Jul 21, 09:06 AM · #

  26. Great tutorial but using static objects or variables creates global state which eventually leads to tons of headaches when you don’t know what class is modifying what static variable.

    It’s best to avoid using static unless it’s const variables that never change.

    If you need some variable it should be passed into the constructor.

    Brian · Aug 27, 12:17 AM · #

  27. Yes, global dynamic properties can open a can worm worms (not to mention make unit testing pretty hairy), but it can also be a convenient way to share data across your project. It’s one option, and it might or might not make sense to use based on your project. Thanks for mentioning the pitfalls though, I realize this article doesn’t speak to them.

    Jonathan · Aug 27, 07:40 AM · #

  28. Hi, can you explain how to use it in timeline, I tried and it is giving me this error:
    1119: Access of possibly undefined property vars through a reference with static type com.greenethumb.utils:GlobalVarContainer.

    developar · Sep 3, 03:21 AM · #

  29. It sounds like you are creating an instance of the GlobalVars class and attempting to access its ‘vars’ property at the instance level, but since the ‘vars’ property is static, it can only be accessed at the Class level.

    Use it like (Class level):
    GlobalVarContainer.vars.foo = ‘bar’

    not like (instance level):
    var gvc:GlobalVarContainer = new GlobalVarContainer()
    gvc.vars.foo = ‘bar’

    Also, if you are using the timeline only, you can just append and update properties to the root of your FLA as well, like: MovieClip(root).foo = ‘bar’.

    Jonathan · Sep 3, 07:53 AM · #

  30. all I wanna do is make a global score … and it says it cant be nested.

    AS3 is totally stupid… AS2 worked just fine

    TURRICAN1024 · Sep 22, 07:05 AM · #

  31. Could you explain what you mean by instance based data coupling. An code walk through would be great.

    arctelix · Dec 10, 11:02 AM · #

  32. sure, its basically storing data on an instance of a class, instead of on the class itself.

    Here is an example to illustrate the differences between static and instance based properties:

    You are writing a game and want to track a user’s score. You write a ScoreKeeper class that has static property ‘score’ which is globally read/write-able from anyway in your app. Easy to use, cool!

    However, you now decide that you want to make the game multiplayer, and you still want to use the nice logic you wrote for your scorekeeper class to track all the users’ scores. Since ‘score’ is a static property of your ScoreKeeper class, all references to ScoreKeeper.score refer to the same variable- thus you cannot use that property for more than one player.

    If you made the ‘score’ an instance level property, then you could just generate a new ScoreKeeper class instance for each player, and track individual scores like:

    scoreKeeper1.score = ‘10’;
    scoreKeeper1.score = ‘20’;

    etc..

    Jonathan · Dec 13, 03:28 PM · #

  33. This was a very nice tutorial thnx a lot

    Anthony · Feb 11, 10:51 PM · #

  34. thank you. spent hours trying to solve this problem!

    wayne brady · Jul 20, 05:26 PM · #

  35. niice, works perfect, thanks

    pedrodle · Jul 31, 08:32 PM · #

Name
Email
Website
Message
  Textile Help