我是一名经验丰富的程序员,但刚刚开始使用Flash / Actionscript。我正在研究一个项目,由于某些原因,我需要使用Actionscript 2而不是3。
当我运行以下内容时(我只是把它放在新的flash项目的第一帧中),输出是3而不是1?我需要它是1。
为什么'ii'变量的范围在循环之间继续?
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
fs[i] = function(){
trace(ii);
}
}
fs[0]();
答案 0 :(得分:2)
不幸的是,AS2不是那种语言;它没有那种封闭。函数在AS2中并不完全是一等公民,其结果之一是函数不保留自己的范围,它在被调用时必须与某个范围相关联(通常与函数的范围相同)本身已定义,除非您使用函数的call
或apply
方法。
然后当函数执行时,其中的变量范围只是它被调用的地方的范围 - 在你的情况下,你的循环范围之外的范围。这也是你可以做这样的事情的原因:
function foo() {
trace( this.value );
}
objA = { value:"A" };
objB = { value:"B" };
foo.apply( objA ); // A
foo.apply( objB ); // B
objA.foo = foo;
objB.foo = foo;
objA.foo(); // A
objB.foo(); // B
如果你习惯了看起来很奇怪的真正的OO语言,原因是AS2最终是prototyped language。看起来面向对象的一切只是巧合。 ; d
答案 1 :(得分:0)
不幸的是,Actionscript 2.0的范围不大......特别是在时间线上。
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
fs[i] = function(){
trace(ii);
}
}
fs[0]();
trace("out of scope: " + ii + "... but still works");
答案 2 :(得分:0)
我想出了一种针对我自己问题的存储解决方案:
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
f = function(j){
return function(){
trace(j);
};
};
fs[i] = f(ii);
}
fs[0](); //1
fs[1](); //2
fs[2](); //3