我正试图逐渐增加反击。以下作品:
function _award(points){
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( "_change_score_by("+diff+");" /* sigh */,
step * 25);
points -= diff;
step++;
}
}
但是,它使用隐式eval。邪恶!让我们使用一个闭包,对吗?
function _award(points){
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( function(){ _change_score_by(diff); },
step * 25);
points -= diff;
step++;
}
}
显然,这不起作用。创建的所有闭包捕获函数中的最后一个值diff
- 1.因此,所有匿名函数都会将计数器增加1,例如,_award(100)
会将得分增加28。
我该如何正确地做到这一点?
答案 0 :(得分:10)
这是一个已知问题。但是你可以在每次循环迭代时轻松创建一个闭包:
(function(current_diff) {
setTimeout(function() {_change_score_by(current_diff);},
step * 25);
})(diff);
答案 1 :(得分:3)
使用ECMAScript第五版Function#bind
方法解决闭包循环问题变得不那么混乱:
setTimeout(_change_score_by.bind(window, diff), step*25);
您可以hack this feature进入不支持它的浏览器,以便立即获得好处。
答案 2 :(得分:2)
Nikita's approach有效(谢谢!),但我个人更喜欢将其更改为更明确的方式:
function _schedule_score_change(diff, step){
setTimeout( function(){ _change_score_by(diff) },
step*25 );
}
function _award(points){
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
_schedule_score_change(diff, step);
points -= diff;
step++;
}
}