admin管理员组文章数量:1356914
I'm trying to have a counter increase gradually. The following works:
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++;
}
}
However, it uses an implicit eval. Evil! Let's use a closure instead, right?
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++;
}
}
Obviously, this doesn't work. All closures created catch the last value diff
has had in the function -- 1. Hence, all anonymous functions will increase the counter by 1 and, for example, _award(100)
will increase the score by 28 instead.
How can I do this properly?
I'm trying to have a counter increase gradually. The following works:
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++;
}
}
However, it uses an implicit eval. Evil! Let's use a closure instead, right?
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++;
}
}
Obviously, this doesn't work. All closures created catch the last value diff
has had in the function -- 1. Hence, all anonymous functions will increase the counter by 1 and, for example, _award(100)
will increase the score by 28 instead.
How can I do this properly?
Share Improve this question edited Oct 17, 2010 at 15:11 badp asked Oct 17, 2010 at 15:00 badpbadp 11.8k5 gold badges64 silver badges89 bronze badges3 Answers
Reset to default 10This is a known problem. But you can easily create a closure on each loop iteration:
(function(current_diff) {
setTimeout(function() {_change_score_by(current_diff);},
step * 25);
})(diff);
Solving the Closure Loop Problem gets less messy with ECMAScript Fifth Edition's Function#bind
method:
setTimeout(_change_score_by.bind(window, diff), step*25);
You can hack this feature into browsers that don't support it yet to get the benefit now.
Nikita's approach works (thanks!), but personally I prefer changing it to this more explicit way:
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++;
}
}
本文标签: Javascript closure quotstoresquot value at the wrong timeStack Overflow
版权声明:本文标题:Javascript closure "stores" value at the wrong time - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744009561a2575313.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论