一道有趣的javascript题目.

有如下两段代码, 第一段代码执行后弹出3次对话框都显示2,
而第二段代码执行后弹出3次对话框分别显示0,1,2.
第二段代码在for循环里比第一段代码多了一层匿名函数自执行.
这时什么原因,谁能解释一下:

[code="java"]function test( num ) {
var funArray = new Array();
for (var i = 0; i < num; i++) {
var trueValue = i;
funArray.push( function() {
alert( trueValue );
});
}
return funArray;
}

var val = test( 3 );
for(var i = 0; i < val.length; i++) {
vali;
}[/code]

[code="java"]function test( num ) {
var funArray = new Array();
for (var i = 0; i < num; i++) {
(function() {
var trueValue = i;
funArray.push( function() {
alert( trueValue );
});
})();
}
return funArray;
}

var val = test( 3 );
for(var i = 0; i < val.length; i++) {
vali;
}[/code]

呵呵,这面试题没仔细想还真会被搞糊涂了,不过单步运行下就很清楚了。这道题的主要问题在于循环体中的trueValue。[code="js"]for (var i = 0; i < num; i++) {

var trueValue = i;

funArray.push( function() {

alert( trueValue );

});

}
/*这段代码中执行了3次var trueValue = i;因为都是在同一作用域里边,所以每次执行都会覆盖掉上次的结果,最后执行结果必然是var trueValue = 2; 弹出3次2也就不足为奇了*/[/code][code="js"]for (var i = 0; i < num; i++) {

(function() {

var trueValue = i;

funArray.push( function() {

alert( trueValue );

});

})();

}

/*
这段代码执行了3次匿名函数
function() {

var trueValue = i;

funArray.push( function() {

alert( trueValue );

});

}
也就是创建了3个不同的匿名function对象,这些function对象拥有各种的trueValue属性,也就是说3个trueValue变量有不同的作用域,所以每次alert出来的都是不同的trueValue。
*/ [/code]

[code="java"]   function f(){
  var n = 999;
  function f1(){
   alert(n+=1);
   }
   return f1;
  }
  var result = f();
  result(); // 1000
   result(); // 1001
   result(); // 1002
[/code]
这是一段闭包的代码,与第一段相似

for (var i = 0; i < num; i++) {

var trueValue = i;

funArray.push( function() {

alert( trueValue );

});

}
第一段代码:循环3次后,trueValue=2,数组内是方法,没执行,由循环外执行,就由如上面的闭包方法得出alert(2)
第二段:多了自执行,循环内就执行了,没有形成闭包

[quote]第一段代码:循环3次后,trueValue=2,数组内是方法,没执行,由循环外执行,就由如上面的闭包方法得出alert(2)
第二段:多了自执行,循环内就执行了,没有形成闭包
[/quote]
学习了。。。

结果的数值肯定是变量作用域,只能说代码的逻辑是闭包
我想前面应该是忽略了,仔细看这是一个嵌套闭包
第一种外闭包先执行,再执行了内闭包
第二种先执行了内闭包,再外闭包
第三种跟第二种一样,结果是3,循环3次是2,没有赋值变量,i++还是会执行,就变成了3

好像说得有点绕了,连我自己都看糊涂了,其实把循环拆开了就很明了了。
第一段代码等价于:
[code="js"]function test( ) {

var funArray = new Array();

var trueValue = 0;  
funArray.push( function() {  
    alert( trueValue );  
}); 

var trueValue = 1;  
funArray.push( function() {  
    alert( trueValue );  
});

var trueValue = 2;  
funArray.push( function() {  
    alert( trueValue );  
}); 

return funArray;  

}

var val = test( );

for(var i = 0; i < val.length; i++) {

vali;

} [/code]
第二段代码等价于:[code="js"]function test( ) {

var funArray = new Array();

(function() {

var trueValue = 0;

funArray.push( function() {

alert( trueValue );

});

})();

(function() {  
    var trueValue = 1;  
    funArray.push( function() {  
        alert( trueValue );  
    });  
})();

(function() {  
    var trueValue = 2;  
    funArray.push( function() {  
        alert( trueValue );  
    });  
})();

return funArray;  

}

var val = test( );

for(var i = 0; i < val.length; i++) {

vali;

} [/code]