this just refers to whatever instance of an object the code is running from. It is implied when you access a variable defined by the class so it is optional. When it comes in handy is when you have variables in a function scope that have the same name. For example:
public class ScopeExample{
var scope:int = 5;
public function doSomething(scope:int):void{
trace(this.scope); // traces 5
trace(score); //traces whatever was passed in the function call
}
}
I like to do this because I like to keep my variable names simple and I don’t want to come up with a new name for a function variable when it has the same purpose as the class variable.
As for your main question, that’s because when you access root directly it is typed as a DisplayObject and that class doesn’t have that variable you are trying to access. When you set it equal to var r, it has no type associated to it so it is typed as Object, and you can access identifier because of that.
var r;
is equivalent to
var r:Object
If you typed r as a DisplayObject you would get the same error as directly accessing root. You could also cast root as an Object and then access any property that isn’t defined.
Object(root)
However you shouldn’t do this because the compiler wont catch you if you try to access something that isn’t there. If you made a typo you would only know during a run time error and those are much harder to catch. What you should do instead is cast root as whatever class the document class is. So: