有如下两段代码, 第一段代码执行后弹出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]