简体   繁体   English

AVM /编译器/范围处理AS3变量

[英]AS3 variables handling by AVM/compiler/scope

I have couple of questions about AS3 variables handling by AVM/compiler/scope 我对AVM /编译器/范围处理AS3变量有几个问题

.1. .1。 This code in Flash will throw an error: Flash中的以下代码将引发错误:

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). 但不会在Flex中引发错误(仅在编辑器中警告)。 Why? 为什么?


.2. .2。 How Flash sees variables in loops? Flash如何在循环中看到变量? 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? 因为它将在Flash中再次引发错误,但在Flex中却不会? Is Flash changing somehow my loop before compilation? Flash在编译前是否以某种方式更改了我的循环?


.3. .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`sa matter of Flash/Flex compiler)? 在类中与Flash中的时间轴等效的位置-在类中,我会将通常放置在时间轴上的代码放在其中(由于我之前编写的内容,我认为它不是构造函数,或者可能是Flash / Flex编译器的问题)?


@fenomas thanks for explaining, but I checked 1. answer and it is not enitirely true :) this code: @ fenomas感谢您的解释,但我检查了1.答案,这并不是很真实:)这段代码:

 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. 将以严格模式在Flash中进行编译,但会关闭警告模式,并且在编译或运行时不会引发错误。

And it will also compile and execute nicely in Flex (event with -strict -warnings compiler commands) (checked with Flash CS3 and FlashBuilder 4). 而且,它还将在Flex中进行编译并很好地执行(带有-strict -warnings编译器命令的事件)(已通过Flash CS3和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. 相同的代码但未包装在函数中,无论在Flash中打开任何错误模式(严格/警告)时,都会生成编译时错误。

Is that what @back2dos said about Flash Compiler that behaves weirdly? 那是@ back2dos关于行为异常的Flash Compiler所说的吗?

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:) )? 这两个编译器Flash / Flex之间有什么区别(为什么我必须在Flash中更改错误模式,而Flex却不关心任何东西:))?

Well, I will explain to you, how package level ActionScript (classes and global functions) is scoping. 好吧,我将向您解释程序包级ActionScript(类和全局函数)的作用域。

The var statement declares a variable within the scope of the function body it is in. It's visibility is within the whole body. var语句在其所在的函数体的范围内声明一个变量。它的可见性在整个体内。 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! 这太可怕了,但是它是基于废弃的ECMA-Script草稿AS3所基于的。。。 :( :(

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. Flash IDE中的AS3和许多设计人员友好的概念(例如框架)都非常含糊。 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). 从开发人员的角度来看,Flash IDE大约是您可以花钱买到的最差的cr * p(这使其无法成为设计,绘制和动画的出色工具)。 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. 如果您想要清晰一致的行为,我建议您不要使用Flash IDE编译ActionScript或浪费时间尝试找出其行为如此怪异的原因。 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)). 除了它的怪癖之外,它还需要花费很长时间进行编译,并且会对ActionScript产生奇怪的影响(例如将局部变量声明转换为实例字段声明(这可能是问题的根源))。

These are great questions. 这些是很好的问题。 In order: 为了:

  1. By default, Flash Authoring FLAs start in strict mode. 默认情况下,Flash Authoring FLA以严格模式启动。 You can change it in File > Publish Settings > AS3 settings. 您可以在“文件”>“发布设置”>“ AS3设置”中进行更改。 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). 顺便说一句,在比较Flash和Flex时,请确保Flash脚本在类内,因为框架脚本是一个细微的不同动物(如下所述)。

  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. AS3没有块级作用域,因此它实现了一种称为“提升”的实践,在该实践中,编译器将所有声明(而不是赋值)都移到发生它们的函数的开头。 Hence, even though your var statement is inside a loop, declaration occurs only once when the function begins to execute. 因此,即使您的var语句在循环内,函数开始执行时,声明仅发生一次。 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. 因此,如果使用var语句在一个框架脚本中创建局部变量,则当您对同一对象执行不同的框架脚本时,该变量仍然存在。

    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. 这基本上是出于历史原因,但是结果实质上与将所有框架脚本都集成到一个大函数中并与GOTO一起跳转是相同的。 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. 这不仅使您避免需要精确了解框架脚本与类代码的区别,而且由于与我们在此谈论的内容无关的几个原因,它是一种很好的编码实践。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM