我们都知道将字符串传递给setTimeout
(或setInterval
)是邪恶的,因为它在全局范围内运行,有性能问题,如果你注入任何参数可能是不安全的等等。这样做肯定已被弃用:
setTimeout('doSomething(someVar)', 10000);
支持这一点:
setTimeout(function() {
doSomething(someVar);
}, 10000);
我的问题是:有没有理由去做前者?它永远更可取吗?如果不是,为什么甚至允许?
我想到的唯一场景是想要使用存在于全局范围内但已在本地范围内重写的函数或变量。这听起来像是糟糕的代码设计,但是......
答案 0 :(得分:16)
你总是可以通过访问它们作为窗口对象的属性来使用全局变量,比如window.globalVar
(虽然使用全局变量确实不是一个好习惯),所以不,我认为没有好的原因是使用不推荐的语法。
可能出于历史原因允许:正如Felix Kling所提到的,原始语法只允许传递一串代码:
引入了JavaScript 1.0,Netscape 2.0。 使用JavaScript 1.2,Netscape 4.0 引入了传递Function对象引用;自5.0版以来由MSHTML DOM支持。 [source,我的重点]
如果浏览器不再支持使用字符串作为setTimeout
和setInterval
的第一个参数,那么互联网上会有很多代码不再起作用。
答案 1 :(得分:15)
对于那些通过问题重定向的人,为什么传递函数比传递字符串更好。
1:传递字符串会激活编译器
每次必须评估字符串时,都会启动完整的编译器。对于需要它的每次调用。
这不仅速度慢,而且还会破坏所有JIT和浏览器的加速。
2:传递字符串的限制更多。
因为字符串是通过编译器运行的,所以它不能完全绑定到本地范围和变量。
虽然在以下情况下不明显:
window.setInterval("doThing()");
在更复杂的情况下,代码更简洁:
window.setInterval("doThing(" + val1 + "," + val2 + ")");
VS
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);
});
(其他对象可能会或可能不会通过 - 取决于它们是否可以序列化,但通常情况下会非常困难。)