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

时间:2010-04-12 14:45:24

标签: flex flash actionscript-3

关于AVM /编译器/范围的AS3变量处理,我有几个问题

0.1。 Flash中的此代码将引发错误:

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

但它不会在Flex中引发错误(仅在编辑器中发出警告)。为什么呢?


0.2。 Flash如何看待循环中的变量?显然这个:

for (var i:int=0; i<2; i++) {
    var mc:MovieClip=new MovieClip();
}
不等于:
var mc:MovieClip=new MovieClip();
var mc:MovieClip=new MovieClip();
因为它会像之前的Flash一样再次抛出错误,但是在函数中没有Flex吗?在编译之前Flash是以某种方式改变我的循环吗?


0.3。在类中相当于Flash中的时间轴的类中 - 在类I中我将放置通常放在时间轴上的代码(我假设它不是构造函数,因为我之前已经写过,或者它可能是Flash / Flex编译器的问题) )?


@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();
将在严格模式下在Flash中编译,但关闭警告模式并且在编译或运行时不会抛出错误。

它还将在Flex中很好地编译和执行(使用-strict -warnings编译器命令的事件)(使用Flash CS3和FlashBuilder 4进行检查)。

相同的代码,但不包含在函数中会产生编译时错误,无论Flash中是否打开任何错误模式(严格/警告)。

那是@ back2dos关于Flash编译器的行为奇怪吗?

这两个编译器之间有什么区别Flash / Flex(为什么我必须在Flash中更改错误模式而Flex不关心任何事情:))

2 个答案:

答案 0 :(得分:1)

好吧,我将向您解释一下包级别ActionScript(类和全局函数)的范围。

var语句在它所在的函数体的范围内声明一个变量。它的可见性在整个体内。因此以下内容完全有效。

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

这很可怕,但它基于放弃ECMA-Script草案AS3基于......耶! :(

为简单起见,假设所有变量声明实际上都在包含函数体的开头(虽然它们的初始化实际上是在你放置它的地方执行的)

从而

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

等于

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

从第一个问题到复制变量定义的第一段代码,它会导致编译器警告,但就像你只做了一个声明一样。

关于你的第三个问题:根本没有相应的东西。

Flash IDE中的AS3和许多设计师友好的概念(例如框架)都非常含糊不清。从开发人员的角度来看,flash IDE是关于你可以获得的最糟糕的cr * p(它阻止它成为设计,绘图和动画的绝佳工具)。如果你想要清晰一致的行为,我建议你不要使用flash IDE来编译ActionScript,或者浪费时间去试图找出它的行为如此奇怪。除了它的怪癖之外,它需要花费很长时间来编译它对ActionScript做的奇怪事情(比如将局部变量声明转换为实例字段声明(这可能是你问题的根源))。

答案 1 :(得分:0)

这些都是很棒的问题。按顺序:

  1. 默认情况下,Flash Authoring FLA以严格模式启动。您可以在文件&gt;中更改它发布设置&gt; AS3设置。但是,重复的变量定义不是运行时错误,只是创作环境可能会或可能不会发出警告或错误,具体取决于配置以及它是类还是帧脚本。

    顺便说一句,在比较Flash和Flex时,请确保您的Flash脚本位于类中,因为帧脚本是一种微妙的不同动物(如下所述)。

  2. AS3没有块级范围,因此它实现了一种称为“提升”的实践,其中编译器将所有声明(但不是赋值)移动到它们出现的函数的开头。因此,即使您的var语句在循环内,声明只在函数开始执行时发生一次。有关详细信息,请参阅here

  3. 帧脚本有点异常。它们有点像匿名函数,除了在给定时间轴上的所有脚本被认为是在相同的词法范围内。因此,如果使用var语句在一个帧脚本中创建局部变量,则在执行同一对象的不同帧脚本时,该变量仍然存在。

    这基本上是出于历史原因,但结果与将所有框架脚本放在一个大函数中并与GOTO一起跳转基本相同。因此,您应始终将所有实际代码保存在类中,并仅使用框架脚本调用需要与时间轴动画同步的类方法。这不仅可以让您避免需要精确理解框架脚本与类代码的不同之处,而且由于与我们在此讨论的内容无关的几个原因,这是一个很好的编码实践。