在通过变量的过程中保持原始价值



好吧,所以我要做的是单击按钮触发触发以下超时的函数:

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"有正确的答案,但是我可能会补充为什么功能在这里更好:

  1. 正如Barmar所说,字符串评估将在全球范围中。
  2. IDE不会在字符串中突出显示语法,因此它会使您的代码对您和他人的阅读不足。
  3. 评估要慢。
  4. 最重要的是,如果您的字符串的一部分来自不受信任的输入,则可能会导致安全问题(例如,如果字符串的一部分来自您的用户注释数据库,则恶意用户可以在此处添加代码以获取用户的cookie)。

最新更新