好吧,所以我要做的是单击按钮触发触发以下超时的函数:
setTimeout("if (document.getElementById(lightnum).style.backgroundColor=='green'){document.getElementById(lightnum).dataset.dead=1;document.getElementById(lightnum).style.backgroundColor='red';}", 3000);
我遇到的问题是,因为可变的灯名立即重复使用,因此当超时触发时,它引用了lightnum的当前值,而不是创建settimeout时的灯名值。我在这里寻找的功能是,当Settimeout触发3秒后,它最初创建了Lightnum的值。
http://jsfiddle.net/657q2/1/
首先,该代码应处于适当的函数而不是字符串。
关于您的问题,它是这样解决的:
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;
等)的功能中制作本地副本。但是,这仍然不起作用,因为这次调用回调时,它将以copy
最后一次调用此功能的最后一个值来运行(可能但不一定是与您的原始代码相同的行为)。p>您真正想做的是将lightnum
的当前值放置在仅通过回调代码访问的地方;在JS中,这样做的唯一方法就是将其作为参数的函数。这需要上述时髦的"返回函数的函数"语法:内部函数是实际所需的回调,外部函数是"防火墙",可以防止任何外部与所讨论的变量进行干预。
使用闭合而不是字符串:
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
);
" jon"one_answers" ted hopp"有正确的答案,但是我可能会补充为什么功能在这里更好:
- 正如Barmar所说,字符串评估将在全球范围中。
- IDE不会在字符串中突出显示语法,因此它会使您的代码对您和他人的阅读不足。
- 评估要慢。
- 最重要的是,如果您的字符串的一部分来自不受信任的输入,则可能会导致安全问题(例如,如果字符串的一部分来自您的用户注释数据库,则恶意用户可以在此处添加代码以获取用户的cookie)。