在循环之外定义变量是否更好?

时间:2011-11-23 22:23:25

标签: actionscript-3

第二个比第一个好吗?

FIRST:

var count:int=myArray.length;
for(var i:uint=0;i<count;i++)
{
   var str:String=myArray[i].label;
   var somethingElse:Class=...;
   var andAnotherThing:MyInstance=new MyInstance(somethingElse);
   ...
}

SECOND:

var count:int=myArray.length;
var str:String;
var somethingElse:Class;
var andAnotherThing:MyInstance;
for(var i:uint=0;i<count;i++)
{
   str=myArray[i].label;
   somethingElse=...;
   andAnotherThing=new MyInstance(somethingElse);
   ...
}

谢谢。

4 个答案:

答案 0 :(得分:8)

在Actionscript和Javascript中,变量的作用域是函数,而不是块。它被称为可变吊装。

ActionScript 3.0 Variables

  

缺乏块级范围的一个有趣的含义是   只要声明,您就可以在变量声明之前读取或写入变量   它在函数结束前声明。这是因为   称为提升的技术,这意味着编译器全部移动   变量声明到函数顶部。

无论你在函数中声明变量的位置如何,你的代码都会像这样有效:

var count:int;
var str:String;
var i:uint;
var somethingElse:Class;
var andAnotherThing:MyInstance;

count = myArray.length;
for(i=0;i<count;i++)
{
   str=myArray[i].label;
   somethingElse = ...;
   andAnotherThing = new MyInstance(somethingElse);
   ...
}

尽管如此,我仍然倾向于在使用它们的块中声明我的变量主要是出于维护原因和一般清晰度。

答案 1 :(得分:2)

在Flash上​​,答案是无所谓。在变量声明方面,Flash很奇怪。 执行以下操作,看看会发生什么:

for(var i:uint=0;i<count;i++)
{
   var str:String=myArray[i].label;
   var somethingElse:Class=...;
   var andAnotherThing:MyInstance=new MyInstance(somethingElse);
}
var str:String=myArray[i].label;

即使str超出了for循环的范围,你也会得到一个变量重定义警告,这意味着变量只会在for循环中“初始化”一次;

答案 2 :(得分:2)

与其他语言不同,ActionScript不会为自己的范围提供执行块(如for块)。变量的最小范围是函数。所以对于编译器来说,这两个例子都是一样的。实际上,实现是一种称为“变量提升”的技术,其中编译器在范围开始之前移动变量的声明。

这有一些有趣的,如果出乎意料的副作用;你可以在变量“声明”之前有效地“使用”它。例如:

trace(test);  // NaN
var test:Number = 10;
trace(test);  // 10

请注意,第一个跟踪不会失败。

无论如何,要记住的关键是变量是局部作用于函数的。这在处理闭包时尤其重要。

答案 3 :(得分:1)

在ActionScript 3中,我认为这不重要。我相信在其他语言中,循环有它们自己的范围意味着它们中定义的变量在循环之外是不可访问的。

我认为AS3的唯一区别在于它如何影响可读性。在我看来,第一个例子更好。

之前我经常在循环上面定义迭代器以便于阅读:如下所示:

var i:MovieClip;
for each(i in movieClipArray)
{
    trace(i);
}

但是,自从进入各种语言以来,为了保持一致性,我保留了所有内容:

for each(var i:MovieClip in movieClipArray)
{
    trace(i);
}
相关问题