Stacey Mulcahy posted on her blog last night asking "Why is _root evil personified". I posted a bit of a long-winded reply, which I decided to flesh out and re-post here, mainly so that I have my own record of it to point people to when they ask this question (it seems to come up a lot). She also followed up asking the same question about _global, which can be answered in exactly the same manner.

First off, using _root isn't necessarily wrong, but it can cause you some major headaches as you move from the world of scripting small Flash pieces to programming larger projects. If you're building one-offs, prototypes, or other projects that have a limited lifespan, won't expand, and will never be incorporated in a larger system then there's nothing wrong with using _root to hack things together quickly. On the other hand, there's something to be said for learning to do things correctly from the beginning, rather than starting quick-n-dirty then trying to adapt to best practices.

The most important thing is to understand the following implications of using _root, so that you are better able to judge when it is appropriate to do so.

  1. Rigid SWF structure Using _root fixes a structure on your swf that may not exist in all deployment scenarios (you may deploy the swf to be loaded into a larger site framework for example, which shifts _root and breaks your logic. Likewise, you might take the code you wrote and try to apply it to a subclip in a more complex project - suddenly you lose that absolute reference, and your code breaks. This obviously makes your code FAR less portable/reusable. This can be somewhat mitigated by the use of _lockroot, but this is really just a band-aid (and has some limitations I might address in another post).

  2. Poor architecture The use of _root is often a symptom of poor architectural planning. Objects lower in an application object hierarchy (that is, more functionally specific objects) should not directly access objects that are higher in the hierarchy (more project specific). In most cases, communication in this direction should occur via events. Calling _root is the ultimate example of this undesirable tight coupling. The major reason we want to avoid this is to increase code reusability, and reduce the dependency of objects on specific architectures or code structures. I would go out on a limb and say that you can usually make a pretty good judgement about a Flash coder's architectural know-how by counting the number of references to _root and _global you can find in his/her code.

  3. Naming conflicts _root (and _global) is a shared scope and cluttering it with anything that isn't qualified by a package opens the door to name conflicts if your code executes in the same player instance as someone else's who uses this scope. Also, because packages/classes are stored in the _global space, you also run the risk of overwriting entire packages if you are inserting members into _global directly.

  4. Code on the timeline Finally, code on the _root indicates code on the timeline (as we can't currently bind a class to the _root), which is generally something you want to avoid in larger projects.

So how do you work around using _root and _global? Most people use these two objects as a place to create absolute paths to objects, data or functions that are used throughout the project. This capability can be replicated by using the Singleton pattern instead, which solves most of the problems listed above by contextualizing your code (with the possible exception of #2, but that is the subject of a whole other debate). Similar results can be achieved using classes with static members.

// SingletonExample by Grant Skinner, http://gskinner.com/

class com.gskinner.foo.SingletonExample {
 // public vars:
   public var bar:Number = 20;
 
 // private vars:
   static private var instance:SingletonExample;
 
 // initialization:
   // constructor is private to
   // discourage direct instantiation:
   private function SingletonExample() {}
 
 // public methods:
   // method to get the single instance of this class:
   public static function getInstance():SingletonExample {
      if (instance == undefined) {
           instance = new SingletonExample();
       }
      return instance;
    }
}

// in another class:
import com.gskinner.foo.SingletonExample;
...
myBar = SingletonExample.getInstance().bar;

There are obviously a number of places where you do have to use _root, but these are all special cases dictated by the Flash environment. Examples include the use of FlashVars and global coordinates (ex. for shape flagged hitTests or globalToLocal).

So in summation: _root is not inherently evil, it has it's uses but it also has some serious implications that you should fully understand before you use it willy-nilly.