Javascript 在传递变量期间保持原始值
好的,我想做的是当点击一个按钮时,函数触发器会产生以下超时:Javascript 在传递变量期间保持原始值,javascript,Javascript,好的,我想做的是当点击一个按钮时,函数触发器会产生以下超时: setTimeout("if (document.getElementById(lightnum).style.backgroundColor=='green'){document.getElementById(lightnum).dataset.dead=1;document.getElementById(lightnum).style.backgroundColor='red';}", 3000); 我遇到的问题是,因为变量li
setTimeout("if (document.getElementById(lightnum).style.backgroundColor=='green'){document.getElementById(lightnum).dataset.dead=1;document.getElementById(lightnum).style.backgroundColor='red';}", 3000);
我遇到的问题是,因为变量lightnum被立即重用,所以当这个超时触发时,它引用的是lightnum的当前值,而不是创建settimeout时lightnum的值。我在这里寻找的功能是当setTimeout在3秒后触发时,它引用最初创建时lightnum的值
使用闭包而不是字符串:
setTimeout(
(function(ln) {
return function() {
if (document.getElementById(ln).style.backgroundColor=='green') {
document.getElementById(ln).dataset.dead=1;
document.getElementById(ln).style.backgroundColor='red';
}
};
}(lightnum)),
3000
);
使用闭包而不是字符串:
setTimeout(
(function(ln) {
return function() {
if (document.getElementById(ln).style.backgroundColor=='green') {
document.getElementById(ln).dataset.dead=1;
document.getElementById(ln).style.backgroundColor='red';
}
};
}(lightnum)),
3000
);
首先,该代码应该位于正确的函数中,而不是字符串中 关于您的问题,它是这样修复的:
var callback = (function(target) {
return function() {
if (target.style.backgroundColor == 'green') {
target.dataset.dead = 1;
target.style.backgroundColor = 'red';
}
};
})(document.getElementById(lightnum));
setTimeout(callback, 3000);
原始代码的问题在于原始回调中的lightnum
在调用回调时会计算为其值,正如您已经看到的那样。相反,您想要的是以某种方式将其“冻结”到其初始值
这样做的一个尝试是在设置超时的函数中创建本地副本(var copy=lightnum;
etc)。但是,这仍然不起作用,因为这次调用回调时,它将对上次调用此函数时的copy
的最后一个值进行操作(可能但不一定与原始代码的行为相同)
您真正想要做的是将当前值
lightnum
放在只有回调代码才能访问的地方;在JS中,唯一的方法是将其作为参数传递给函数。这就需要使用上面时髦的“返回函数的函数”语法:内部函数是实际需要的回调函数,外部函数是一个“防火墙”,防止任何外部干预所讨论的变量。首先,代码应该在一个适当的函数中,而不是字符串中
关于您的问题,它是这样修复的:
var callback = (function(target) {
return function() {
if (target.style.backgroundColor == 'green') {
target.dataset.dead = 1;
target.style.backgroundColor = 'red';
}
};
})(document.getElementById(lightnum));
setTimeout(callback, 3000);
原始代码的问题在于原始回调中的lightnum
在调用回调时会计算为其值,正如您已经看到的那样。相反,您想要的是以某种方式将其“冻结”到其初始值
这样做的一个尝试是在设置超时的函数中创建本地副本(var copy=lightnum;
etc)。但是,这仍然不起作用,因为这次调用回调时,它将对上次调用此函数时的copy
的最后一个值进行操作(可能但不一定与原始代码的行为相同)
您真正想要做的是将当前值lightnum
放在只可由回调代码访问的地方;在JS中,唯一的方法是将其作为参数传递给函数。这就需要使用上面时髦的“返回函数的函数”语法:内部函数是实际需要的回调函数,外部函数是一个“防火墙”,防止任何外部干预所讨论的变量。“Jon”和“Ted Hopp”有正确的答案,但我可以在此补充为什么函数更好:
你能不能先
var tempLightnum=lightnum
,然后setTimeout(…tempLightnum…,3000)
?我试过了,lightnum一秒钟可以有40多个新条目,所以使用虚拟变量是行不通的,因为它们的输入速度太快了。这个变量会像第一个变量一样出错。你能不能先var tempLightnum=lightnum
,然后setTimeout(…tempLightnum…,3000)
?我试过了,lightnum一秒钟可以有40多个新条目,所以使用虚拟变量是行不通的,因为它们输入的速度太快了。那个变量会像第一个一样搞砸。谁在否决这些?为什么?我不知道。虽然DV已被删除。在对程序进行另一轮测试后,我注意到同样的问题仍然存在。@泰勒:确保您的回调没有引用任何“从外部”可见的变量(例如,上面显示的target
不可能被回调代码以外的任何人访问)。以上代码保证是正确的,鉴于问题中的信息,没有其他建议。以下是我的JSFIDLE javascript:我不太确定你在之前的评论中的意思。谁在否决这些以及为什么?我不知道。虽然DV已被删除。在对程序进行另一轮测试后,我注意到同样的问题仍然存在。@泰勒:确保您的回调没有引用任何“从外部”可见的变量(例如,上面显示的target
不可能被回调代码以外的任何人访问)。以上代码保证是正确的,并且在给定信息的情况下,没有其他建议