开发者

AS3 variables handling by AVM/compiler/scope

I have couple of questions about AS3 variables handling by AVM/compiler/scope

.1. This code in Flash will throw an error:

function myFunction() {
    var mc:MovieClip=new MovieClip();
    var mc:MovieClip=new MovieClip();
}

but it won`t throw an error in Flex (only warning in Editor). Why?


.2. How Flash sees variables in loops? Apparently this:

for (var i:int=0; i<2; i++) {
    var mc:MovieClip=new MovieClip();
}
isn`t equal to just:
var mc:MovieClip=new MovieClip();
var mc:MovieClip=new MovieClip();
because it will throw an error again as earlier in Flash, but in Flex in function not? Is Flash changing somehow my loop before compilation?


.3. Where in a class in equivalent to timeline in Flash - where in class I would put code which I put normally on timeline (I assume it is not constructor because of what I have written earlier, or maybe it`s开发者_开发知识库 a matter of Flash/Flex compiler)?


@fenomas thanks for explaining, but I checked 1. answer and it is not enitirely true :) this code:

function myFunction() {
    var mc:MovieClip=new MovieClip();
    mc.graphics.beginFill(0x0000FF);
    mc.graphics.drawRect(0,0,100,100);
    mc.graphics.endFill();
    addChild(mc);
    var mc:MovieClip=new MovieClip();
    mc.graphics.beginFill(0x000000);
    mc.graphics.drawRect(0,0,30,30);
    mc.graphics.endFill();
    addChild(mc);
}
myFunction();
will compile in Flash in strict mode but with warning mode turned off and won`t throw an error during compile or runtime.

And it will also compile and execute nicely in Flex (event with -strict -warnings compiler commands) (checked with Flash CS3 and FlashBuilder 4).

The same code, but not wrapped in function will generate compile time error regardless off any error modes turned on (strict/warning)in Flash.

Is that what @back2dos said about Flash Compiler that behaves weirdly?

What is the differences between these two compilers Flash/Flex (why I have to change errors mode in Flash while Flex does not care about anything:) )?


Well, I will explain to you, how package level ActionScript (classes and global functions) is scoping.

The var statement declares a variable within the scope of the function body it is in. It's visibility is within the whole body. thus the following is completely valid.

a = 3;
if (Math.random()>0.5) {
    var a:int = 0;
}
else {
    a = 6;
}

this is horrible, but it's based on the abandonend ECMA-Script draft AS3 is based on ... yay! :(

for simplicity, imagine that all variable declarations are actually at the start of the containing function body (while their initialisation is actually performed in the place where you put it)

thus

for (var i:int=0; i<2; i++) {
    var mc:MovieClip=new MovieClip();
}

is equal to

var i:int, mc:MovieClip;
for (i=0; i<2; i++) {
    mc=new MovieClip();
}

the first piece of code from your first question to a duplicate variable defininition, which causes a compiler warning, but works as if you had made only one declaration.

as for your third question: there is no equivalent at all.

AS3 in the flash IDE and many designer friendly concepts (such as frames) are highly ambiguous. from a developer's point of view the flash IDE is about the worst piece of cr*p you can get for money (which stop it from being a great tool for design, drawing and animation). if you want clear and consistent behaviour, I advise you not to use the flash IDE for compiling ActionScript or to waste time on trying to find out why it behaves so weirdly. Apart from its quirks, it takes a long time to compile and the strange things it does to your ActionScript (such as converting local variable declaration to instance field declaration (which is probably the source of your problem)).


These are great questions. In order:

  1. By default, Flash Authoring FLAs start in strict mode. You can change it in File > Publish Settings > AS3 settings. However, duplicate variable definitions are not a runtime error, just something that the authoring environment may or may not throw a warning or error about, depending on configuration and whether it's a class or frame script.

    Incidentally, when comparing Flash and Flex make sure that your Flash scripts are inside a class, since frame scripts are a subtle different animal (as discussed below).

  2. AS3 does not have block-level scope, so it implements a practice called "hoisting", where the compiler moves all declarations (but not assignments) to the beginning of the function in which they occur. Hence, even though your var statement is inside a loop, declaration occurs only once when the function begins to execute. See here for more details.

  3. Frame scripts are a bit anomalous. They're sort of like anonymous functions, except that all scripts on a given timeline are considered to be in the same lexical scope. So if you use a var statement to create a local variable in one frame script, the variable will still exist when you execute a different frame script of the same object.

    This is basically for historical reasons, but the result is essentially the same as having all your frame scripts in one big function and jumping around with GOTOs. Hence you should always keep all your real code in classes, and use frame scripts only to call class methods that you need to be synchronized with timeline animations. This not only lets you avoid needing to understand precisely how frame scripts differ from class code, it's good coding practice for a couple of reasons unrelated to the stuff we're talking about here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜