setTimeout() 与字符串或(匿名)函数引用?快速

IT技术 javascript performance coding-style
2021-03-04 04:30:19

这两种方式中哪一种更快,为什么?

window.setTimeout("func()", 100);

或者

window.setTimeout(function(){func();}, 100);

我猜如果除了 John Resig 和所有 ninjas 之外没有其他原因使用它,我猜第二种方式更快,我猜是因为它已经解析,而不是它必须创建一个新的解析“thingie”的第一种方式”。我依稀记得这是人们不喜欢 eval() 的原因之一。

另外,虽然我在这里有你,但在第二个代码片段中,在这种情况下,第一个分号是否被认为是好的做法?

5个回答

还有第三个更快/更简单的选项:

window.setTimeout(func, 100);

...与您的问题严格相关,第二个更快,因为它仍然是参考 - 而不是评估,评估总是相当昂贵。至于分号,是的,始终使用它们是一个好习惯。在我看来,它们永远不应该是可选的,但在这里很多人会不同意我的观点。你真的不能反驳是在你的代码,这始终是一个明确的东西。

实际上你可以使用 setTimeout(func, 100, arg1, arg2, ...) 如果你愿意,但在这种情况下,我的选择是字符串在可读性方面获胜: setTimeout("func(arg1, arg2, ...) )”, 100)。
2021-04-26 04:30:19
@qwerymk、@martona,带有额外参数的语法不适用于 IE。
2021-05-04 04:30:19
分号问题最近又出现了,可以公平地说,以下作者确实不同意@Nick:blog.izs.me/post/2353458699/...
2021-05-04 04:30:19
@qwertymk - 这是正确的,但在你的例子中没有(大多数时候你在野外看到这个,也没有)。
2021-05-05 04:30:19
第三种选择仅在没有参数时
2021-05-17 04:30:19

正如您所写的,两者都同样“安全”。当您尝试传递参数时会出现安全问题,因为有这样做的诱惑:

setTimeout('func('+arg+')', 100);

这具有代码注入的潜力。有人用它来摧毁你的死星。迟早,年轻的绝地武士会想出如何欺骗您的应用程序使其arg等于3.14); deathStar.selfDestruct(,然后您知道,您将接到皇帝的电话,解释您的错误。

而且可能不是你犯了错误……你永远不会做这么愚蠢的事情。当你的代码在 6 个月后被实习生重构并且他们需要添加一个参数时,问题就来了。

所以字符串形式只是被认为是不好的做法。它更慢,而且可能不太安全。

最好这样做: setTimeout("func", 100, arg);
2021-04-21 04:30:19

在内部使用带有字符串语法的“setTimeout”使 javascript 引擎“评估”它。每当浏览器在代码中的任何地方遇到“eval”时,它都无法进行许多优化(因此禁用它们),因为任何东西都可以进入 eval。

诸如缓存变量之类的优化不能使用代码中存在的 'eval' 来完成,因为 'eval' 可能会引入新的变量,这些变量在 Javascript 的编译阶段(它检测所有声明)将被忽略。

第二种语法更快,因为它只会在延迟后调用该函数,而您不会陷入“eval”的弊端。

你提到的人使用它可能不是因为它更快。

  • 替代语法中的代码是您要在延迟毫秒后执行的代码字符串。(出于与使用 eval() 相同的原因,不建议使用此语法)

来自https://developer.mozilla.org/en/DOM/window.setTimeout

我不认为在现代浏览器中任何一个都明显更快。即使速度稍快,您的代码不会过于频繁地调用 setTimeout 这一事实也使这一点毫无意义。

第一个的好处是更具可读性,这将是我的偏好。

嗯...如果你打算通过 prompt() 来让你的 UI 工作,让用户调用函数,或者为函数名称发出 HTTP 请求,那么是的,这是不安全的。
2021-05-10 04:30:19
该字符串可能会稍微更可读的,但它的很多更不安全。
2021-05-17 04:30:19