【问题标题】:Is there ever a good reason to pass a string to setTimeout?是否有充分的理由将字符串传递给 setTimeout?
【发布时间】:2011-08-30 04:59:24
【问题描述】:

我们都知道将字符串传递给setTimeout(或setInterval)是邪恶的,因为它在全局范围内运行,存在性能问题,如果您注入任何参数可能会不安全等等。所以绝对不推荐这样做:

setTimeout('doSomething(someVar)', 10000);

赞成这个:

setTimeout(function() {
    doSomething(someVar);
}, 10000);

我的问题是:有没有理由做前者?它曾经更可取吗?如果不是,那为什么还要允许呢?

我想到的唯一方案是想要使用存在于全局范围内但已在本地范围内被覆盖的函数或变量。在我看来,这听起来像是糟糕的代码设计,但是......

【问题讨论】:

  • 基于 MDC's documention 似乎传递字符串是一开始的唯一选择(至少在 Firefox 中)。我可以想象他们不会限制传递字符串以不制动兼容性......找不到太多其他为什么(还)。
  • @Felix:确实,我也在文档中寻找那部分。有趣的是,一个明显的拼写错误实际上使您的陈述更加有效(“刹车”应该是“休息”)。 ;-)
  • “如果不是,为什么还要允许?” - 这绝对不是 JavaScript 中唯一从不有用和邪恶但被允许的东西......

标签: javascript settimeout


【解决方案1】:

您始终可以通过将全局变量作为窗口对象的属性访问它们来使用它们,例如window.globalVar(尽管使用全局变量确实不是一个好习惯),所以不,我认为没有充分的理由使用不推荐使用的语法。

这可能是历史原因允许的:正如 Felix Kling 提到的,原始语法确实只允许传递一串代码:

在 JavaScript 1.0、Netscape 2.0 中引入。 在 JavaScript 1.2、Netscape 4.0 中引入了传递函数对象引用;自 5.0 版起受 MSHTML DOM 支持。 [source,我的重点]

如果浏览器不再支持使用字符串作为setTimeoutsetInterval 的第一个参数,那么互联网上将会有很多代码不再起作用。

【讨论】:

  • 从 SO 上使用字符串的示例数量来看......不幸的是,这是非常正确的。
  • @472084 是的,癌症应该被治愈。
【解决方案2】:

对于那些被为什么传递函数比传递字符串更好的问题重定向到这里的人。

1:传递字符串会启动编译器

每次你必须评估一个字符串时,你都会启动一个完整的编译器。对于需要它的每个调用。

这不仅速度很慢,而且会破坏所有已完成的 JIT 和浏览器加速。

2:传递字符串受到更多限制。

因为字符串是通过编译器运行的,所以它没有完全绑定到本地范围和变量。

虽然在以下情况下并不明显:

window.setInterval("doThing()");

在更复杂的情况下,代码更简洁:

window.setInterval("doThing(" + val1 + "," + val2 + ")");

window.setInterval(function() {
  // You can put a debugging point here
  dothing(val1, val2);
});

3:DOM对象不能通过字符串传递

正如 Álvaro 提到的,DOM 对象不能通过字符串方法传递。

// There is no way to do this via a string.
var el = document.getElementById("my-element");
window.setInterval(function() {
  dothing(el);
});

(其他对象可能通过也可能不通过 - 取决于它们是否可以序列化,但通常会非常困难。)

【讨论】:

  • 更不用说何时需要将对象作为参数传递(DOM 节点、日期...)。
  • @ÁlvaroG.Vicario 啊,是的!优秀。我会补充的。
猜你喜欢
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
相关资源
最近更新 更多